URL Encoding Explained: Why Links Break and How to Fix Them

By James Ephrim, founder of PrivateToolbox10 min read

You have seen the symptoms even if you have never heard the name. A shared link that arrives with %20 where the spaces were. A campaign link that tracks the wrong thing. A search link that returns results for half your query and ignores the rest. A download link that works when you click it and fails when you paste it into a message. In almost every case, the culprit is URL encoding — or rather, encoding applied in the wrong place, or not applied where it was needed.

This guide explains URL encoding the practical way: what percent-encoding is, the one rule that prevents most breakage (encode each value as you build the link, not the finished link as a whole), five real ways links break, and the cases where encoding is not the fix at all. All the examples are verified against the same browser functions our free URL Encoder & Decoder uses, so you can paste any of them into the tool and get exactly the result shown here.

What percent-encoding actually is

A URL can only safely carry a limited set of characters: letters, digits, and a handful of punctuation marks. Everything else has to be translated before it travels, and the translation is percent-encoding: the character is converted to its bytes, and each byte is written as a % followed by two hexadecimal digits. A space becomes %20. An ampersand becomes %26. A question mark becomes %3F. A literal percent sign becomes %25, because a bare % would otherwise look like the start of an encoded sequence.

Non-English characters take the same route, just with more bytes. The é in café is two bytes in UTF-8, so café encodes as caf%C3%A9 — one % sequence per byte, not per letter. That is why an encoded link in another language can look dramatically longer than the original text: every accented character, and every character in a non-Latin script, expands to two or more % sequences. The link still works; it is just wearing its travel clothes.

Decoding is the reverse trip: %20 back to a space, %26 back to an ampersand, %C3%A9 back to é. It is a mechanical translation, not a disguise. Anyone can decode a percent-encoded string in one step, which matters for the security section later: encoding makes text safe to transport inside a URL, and it does nothing at all to make it safe to read.

The one rule: encode each value, not the finished link

A URL has two kinds of characters: structure and content. The : / ? & = and # characters are structure — they tell the browser where the host ends, where the path starts, and where one parameter ends and the next begins. Everything inside a value is content. Encoding confuses the two at your peril, because the two browser functions treat them differently by design.

Encode a whole URL, and you want the structure left alone. Encoding https://example.com/search?q=hello world&lang=en as a whole URL gives https://example.com/search?q=hello%20world&lang=en — only the space changed, and the link still works. Encode that same finished link as if it were one value, and its : and / turn into %3A and %2F, and you no longer have a link at all, just a string that looks encoded.

Encode one value, and you want everything encoded, including characters that would otherwise read as structure. The search term hello world & friends? as a single value encodes to hello%20world%20%26%20friends%3F — the ampersand and the question mark are encoded precisely because, inside a value, they are data, not separators. If you encoded that value the gentle way instead, the & would survive unencoded, and the server would read friends? as a second, separate parameter. Your search for one phrase would silently become a search for hello world plus a mystery parameter.

So the rule is: encode each value at the moment you put it into the link, and only tidy up a finished URL if it still contains unsafe characters. A product name like fish & chips becomes fish%20%26%20chips as a value. A path segment like a/b becomes a%2Fb, because an unencoded slash inside a segment would be read as a path separator. Get this rule right and most encoding bugs disappear; get it backwards and you will spend an afternoon wondering why a link works in one place and breaks in another.

When encoding is not the fix

Encoding solves transport problems: characters that cannot travel safely inside a URL. It does not solve meaning problems. If a server expects a parameter called q and you send query, no amount of encoding will make it work. If a server decodes with the wrong character set, non-English text will arrive garbled even though the encoding was correct — that is a server configuration issue, and the fix belongs on the server, not in your link.

Encoding is also not encryption, and the confusion with Base64 is worth clearing up. Base64 is a different encoding for a different job: it turns binary data into plain text characters so it can travel in places like JSON or email, and our Base64 Encoder & Decoder covers it. Neither encoding hides anything — both are reversible in one step — so never encode a password, a token, or a private link and treat it as protected. If content needs to stay secret, it needs real encryption, and it should not be sitting in a URL query string in the first place, where it ends up in server logs, browser history, and shared links.

One more caution, because it costs people real privacy: pasting a live link into a random online encoder hands that link to whoever runs the site. Pre-signed download URLs, password-reset links, and API endpoints with tokens in the query string all work for anyone who holds them. That is why our encoder runs entirely in your browser tab — the link you are fixing never leaves your device, which matters most exactly when the link is the sensitive thing.

A workflow that avoids all five traps

  1. Build the link value by value. Encode each query value and each path segment as you add it, using the one-value encoding, and leave the structure characters alone.
  2. Before you publish the link, paste it into the query parser on our URL Encoder & Decoder. Check that every parameter appears once, with the decoded value matching what you intended — no split values, no surviving % sequences.
  3. If a link arrives broken, decode it first and compare it with the original. The difference between the sent and received versions usually names the trap: a split value, a double-encoded sequence, a stray %, or a plus that changed meaning.
  4. Test the link the way your readers will receive it: click it, and also paste it into the channel you will actually share it through. A link that survives both trips is a link you can trust.

That is the whole discipline, and it fits in a checklist because the underlying idea is simple: structure stays structure, content gets encoded, and anything that still looks encoded after decoding was encoded twice. Once you can read a percent-encoded link the way you read ordinary text — %20 as a space, %26 as an ampersand, %2520 as a warning sign — broken links stop being mysterious and start being diagnosable.

Quick answers to common questions

When do I encode the whole URL, and when do I encode one value?

Encode one value whenever you are building a link: each query value and each path segment gets fully encoded, including & = ? and /. Encode a whole URL only when you already have a finished link that still contains unsafe characters like spaces — the whole-URL encoding leaves : / ? & = # intact so the link keeps working. Encoding a finished link as one value breaks it; encoding a single value the gentle way leaves its & unencoded and splits it into extra parameters.

Why do some links use %20 for spaces and others use +?

%20 is the URL standard for a space. The + comes from form encoding, the format browsers use when submitting HTML forms, where servers decode + back to a space. In a plain URL path or a JSON API query, + is a literal plus sign, not a space. Use %20 unless you know the receiver expects form encoding.

What is double-encoding, and how do I spot it?

Double-encoding is encoding an already-encoded value a second time, so %20 becomes %2520. The server decodes once and gets %20 as literal text instead of a space. Spot it by decoding the value: if % sequences survive decoding, the value was encoded twice.

Why does decoding fail with a malformed-sequence error?

Because the input contains a % that is not followed by exactly two hexadecimal digits — a lone % at the end, %ZZ, or a sequence cut off by copy-paste. A literal percent sign in the original text must itself be encoded as %25. Fix the stray % and decode again.

Does URL encoding hide or protect sensitive data?

No. Encoding is fully reversible by anyone, and it only changes how characters travel inside a URL. Never put secrets in a URL query string if you can avoid it, and never treat encoding as a substitute for encryption.