URL Encoding Explained: Why Links Break and How to Fix Them
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.
Five ways links break, and how to spot each one
1. An unencoded ampersand splits one value into two parameters
This is the most common breakage, and it usually arrives via a campaign link. A UTM value like summer & autumn sale, pasted raw into a URL, becomes utm_campaign=summer & autumn sale — and the server reads utm_campaign=summer, then a parameter called autumn sale with no value. Your analytics show a campaign called summer and a ghost parameter nobody recognises. The fix is to encode the value before it goes in: summer%20%26%20autumn%20sale. If a campaign report ever shows a truncated name, check the raw link for a bare & first.
2. A plus sign that means a space in one place and a plus everywhere else
A space encoded as %20 is the URL standard, and it is what browsers produce. But form data — the format browsers use to submit HTML forms — traditionally writes a space as +. So a server that reads form data will turn + back into a space, while a server reading a plain URL will treat + as a literal plus sign. If your query for a+b comes back as results for a b on one system and a+b on another, neither system is broken; they are just reading different rulebooks. Unless you know the receiver expects form encoding, %20 is the safe choice, and a%2Bb is the correct encoding of a literal plus.
3. Double-encoding: %20 becomes %2520
Double-encoding happens when an already-encoded value is encoded a second time. The % in %20 is itself encoded as %25, so hello world becomes hello%2520world. The link still looks encoded, which is what makes this trap so annoying: the server decodes it once and gets hello%20world as literal text, not hello world. The tell is a decoded value that still contains % sequences. Paste the suspicious link into our tool's query parser and look at the decoded column — if % sequences survive decoding, the value was encoded twice, and decoding once more (or fixing the code that encoded it twice) is the cure.
4. A literal percent sign that was never encoded
A value like 50% off contains a % that is not the start of an encoded sequence, but a decoder does not know that — it expects exactly two hexadecimal digits after every %. A bare % at the end of a value, or %ZZ, or %2 with only one digit, makes decoding fail outright with a malformed-sequence error, rather than guessing. The correct encoding is 50%25%20off. If a link fails to decode, look for a stray % before anything else, and check for sequences cut off by copy-paste.
5. A link that breaks only after being shared
Some links work when clicked and break when pasted into a chat app, an email client, or a document, because the app re-encodes, wraps, or truncates the URL, or strips characters it considers unsafe. If a link works from your browser and fails from a message, decode the version that arrived, not the version you sent: paste the received link into the decoder and compare it character by character with the original. The difference — a doubled % sequence, a dropped character, a space inserted by line-wrapping — is usually visible in seconds once both versions sit side by side.
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
- 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.
- 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.
- 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.
- 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.