URL decode
Turn %E2%9C%93 back into ✓. Double-encoded strings, form encoding and half-broken input are all handled rather than refused. Nothing is stored.
- Never stored
- No queue, no waiting
- No signup, no watermark
Decoded appears here.
How it works
Paste the encoded text
A whole URL, a query string, or just one value.
Pick the flavour if needed
Standard decoding, or form decoding where + means space. If you are unsure, the page shows you when the two differ.
Copy the result
Decode again if the text was encoded twice — which is common, and easy to spot once you see it.
The ambiguity nothing can resolve for you
Decoding is mechanically simple — find each % followed by two hex digits, turn it back into a byte, then read the bytes as UTF-8 — and it has exactly one genuine ambiguity. A plus sign might mean a space, or it might mean a plus. In a submitted form it means a space, by a convention older than the web's own URL specification. In a path segment it is a literal character. Nothing in the text itself says which applies, so the page shows you both readings rather than picking one and being quietly wrong — which matters most for the case where it bites hardest, an email address or a base64 value where a plus is real data.
Non-ASCII text arrives as several percent sequences per character, because encoding works on UTF-8 bytes rather than on characters: an accented letter is two, most symbols three, an emoji four. Decode a sequence that is not valid UTF-8 and you get replacement characters — usually a sign that the text was encoded from a different character set, or that it has been cut short partway through a character.
Decoding twice is a security bug, not just a mistake. If a value is decoded, checked, and then decoded again, an attacker can hide characters from the check: %252e%252e%252f passes a filter looking for "../" because after one pass it is still %2e%2e%2f, and after the second it is the traversal the filter was there to stop. Decode exactly once, then validate, and never in the other order.
Text that was never encoded comes back unchanged rather than mangled, which is the useful behaviour when you are not sure whether a string needs decoding at all. A percent sign that is not followed by two hex digits is left alone rather than treated as an error — that is a literal percent, common in text that was pasted rather than encoded.
When you want something else
In code, the decoder should match the encoder. JavaScript has decodeURIComponent; Python separates unquote from unquote_plus on precisely the plus-sign question; PHP has rawurldecode and urldecode for the same reason. Better still, let a URL type or a query-string parser do it — most frameworks decode parameters for you, and decoding again afterwards is how the double-decoding bug above gets written.
For inspecting a long URL rather than decoding a value, a parser beats a decoder: python -c "import urllib.parse,sys; print(urllib.parse.urlparse(sys.argv[1]))" splits an address into its parts so you can see which piece is which before decoding anything, which is usually the actual question when a link is misbehaving.
Frequently asked questions
My text still has %25 in it after decoding
Then it was encoded twice, which is extremely common — it happens whenever an already-encoded value gets encoded again on its way through a redirect or a logging layer. %25 is the encoding of the % character itself, so the first decode turns %2520 into %20, and a second decode turns that into a space. Just decode again. The page tells you when it spots the pattern.
Should "+" become a space?
It depends where the string came from, which is why it is a choice rather than a guess. In an application/x-www-form-urlencoded body — a submitted HTML form — + means space. In a path segment, or in data that merely travelled through a URL, + is a literal plus character and turning it into a space corrupts the value. Base64 strings are the case that bites: they contain real + characters, and form-decoding one destroys it.
What happens with a broken string?
It decodes what it can and leaves the rest alone, rather than refusing everything. A stray % that is not part of a valid escape — common when text has been partly decoded already, or truncated — makes the browser's own decoder throw an error and return nothing. Here, every valid escape is decoded and the stray characters are left as they are, which is far more useful when you are trying to read a broken log line.
Is my text stored anywhere?
No. Nothing is stored and no request is made. You can disconnect from the internet after the page loads and it keeps working.
Can I decode a whole URL at once?
Yes. Paste the entire thing — the structure is left readable and only the encoded parts are turned back into text, so a long URL with several encoded parameters becomes something you can actually read.
Good to know: A plus sign is ambiguous: in a query string it means a space, and in a path it means a literal plus. The page decodes both ways and shows you which is which rather than guessing. Text that was never percent-encoded is returned unchanged rather than mangled.
Put this tool on your website
Free for any blog, class page or help article. Paste one snippet and your visitors can use it right on your page.