I’ve been having the same issue. I’ve poked around in the Hugo code base and found the solution. There’s an undocumented built-in Hugo function wrapping the Golang url.QueryEscape function:
url.QueryEscape
You can use it with Hugo like this:
{{ urlquery .Permalink }}