What Is URL Decode (urldecode) and How Do You Decode an Encoded URL?

Updated

URL decoding (often called urldecode) reverses percent-encoding: it turns sequences like %20, %2F, and %E2%82%AC back into the characters they represent (a space, /, and €). You need it whenever a URL or form value arrives in encoded form and you want to read, compare, or store the original text. The main conditions for getting it right are knowing which encoding was used (almost always UTF-8 today), whether + means a space in your context, and decoding exactly once.

What urldecode actually reverses

URLs can only contain a limited set of characters. Everything else is escaped as a percent sign followed by two hexadecimal digits representing a byte.

Encoded Decoded Note
%20 space Most common encoding of a space in a path or query
+ space Only in application/x-www-form-urlencoded data (query strings, form posts)
%2F / A slash that is data, not a path separator
%26 & An ampersand inside a value, not a parameter separator
%3D = An equals sign inside a value
%E2%82%AC € Multi-byte UTF-8 character (three bytes)

Two consequences follow from this table:

  • + is ambiguous. In a query string it usually means a space, but in a path segment it is a literal plus. Decoders differ, so check which convention your tool applies.
  • Multi-byte characters arrive as several %XX groups. %E2%82%AC is one character, not three. Decoding byte-by-byte without reassembling UTF-8 produces mojibake.

How to decode a string

With an online decoder

Sites such as urldecode.org offer a single Encode/Decode interface: paste the encoded string, run the decode action, and read the result. This is the fastest route for a one-off value.

  1. Copy the encoded text exactly, including any leading or trailing % sequences.
  2. Paste it into the decoder input.
  3. Run decode and compare the output against what you expect the original to be.
  4. If the result looks like garbled symbols, the source was probably not UTF-8 — see the pitfalls below.

In code

Most languages ship a decoder in the standard library. The input is the encoded string; the action is a single decode call; the expected result is the original text.

from urllib.parse import unquote, unquote_plus

unquote("caf%C3%A9")          # 'café'  — %XX only
unquote_plus("a+b")           # 'a b'   — treats + as space
decodeURIComponent("caf%C3%A9");   // 'café'
decodeURIComponent("a+b");         // 'a+b'  — + is NOT a space here

Note the difference: decodeURIComponent leaves + alone, while Python's unquote_plus converts it to a space. Pick the function that matches how the string was encoded.

Verify the result

A decode is correct when re-encoding the output reproduces the input (modulo case of hex digits and + vs %20). If round-tripping changes the string, you either decoded twice or used the wrong + rule.

Decoding a whole URL vs. a single parameter value

This distinction causes most real-world bugs.

  • Decoding a full URL turns %20 into spaces and %2F into slashes, which can destroy the structure: a path separator that was safely encoded becomes a real separator. Decode individual components, not the assembled URL, unless you specifically want the human-readable form.
  • Decoding a query parameter value is the normal case. Given ?q=url+decode%20guide, the value is url+decode%20guide; decoding it with the form rule yields url decode guide.

Rule of thumb: split the URL into its parts first, then decode each part with the rule that matches its origin.

Common pitfalls

Double-decoding

If a value was encoded once, decoding twice turns a literal %2520 (which means %20) into a space when it should stay as %20. Decode exactly once per layer of encoding, and only when you know a layer exists.

Treating + as a space everywhere

+ means space only in form-encoded data. In a path or a fragment it is a literal plus. Using unquote_plus on a path segment silently corrupts values.

Assuming UTF-8

Older systems may use ISO-8859-1 or a local codepage. %E9 is é in ISO-8859-1 but an invalid standalone byte in UTF-8. If the output is garbled, try decoding the bytes with the source's declared charset before converting to text.

Decoding before splitting

Decoding a query string before splitting on & and = lets an encoded %26 become a real separator and split one value into two. Split first, decode second.

Quick check: is this string actually encoded?

Look for % followed by two hex digits (%20, %2F, %C3%A9) or, in query strings, + where a space is expected. A string with no %XX pattern and no meaningful + is almost certainly already plain text — decoding it changes nothing, but decoding it twice can still cause damage if it contains a literal %. When in doubt, decode once and confirm the output reads as the text you expected.