Upload a file
  1. base64hub
  2. Web & token tools
  3. URL decode

URL Decoder (Percent-Decoding)

Paste an encoded URL, query string or log line to turn %20, %2F and %C3%A9 back into text. Full URLs are also split into host, path and decoded query parameters.

Free no sign-up, no limits Local nothing uploaded Repeat unwraps double and triple encoding, up to 5 rounds Updated Oct 27, 2026
Input 0Output 0

Processed in your browser. This page cannot send your data anywhere – how we know

How to decode a URL

  1. Paste the encoded text into Encoded URL or text.
  2. Keep Treat + as space on for query strings and form data, and turn it off for paths or Base64 values.
  3. If the result still contains %XX sequences, the status suggests it: tick Decode repeatedly.
  4. For a log file or a column of values, tick Each line separately so every line is decoded on its own.
  5. Pick a Charset if the source was not UTF-8, then Copy output.

When the input is a full URL, the table below the panes shows the scheme, host, decoded path, each query parameter on its own row, and the fragment. That is the quickest way to read a long tracking or redirect URL.

Examples

EncodedDecodedNote
q=base64%20%26%20%22url-safe%22q=base64 & "url-safe"%26 is &, %22 is "
lang=%E6%97%A5%E6%9C%AC%E8%AA%9Elang=日本語three bytes per character in UTF-8
%F0%9F%98%80😀emoji take four bytes
q=a+b%2Bcq=a b+cwith Treat + as space
next=%252Fhome%253Ftab%253D1next=/home?tab=1double-encoded, two rounds
caf%E9caféWindows-1252 or ISO-8859-1, not UTF-8

Double encoding

Each time an already encoded string is encoded again, every % becomes %25. So / turns into %2F, then %252F, then %25252F. It happens when a redirect URL is passed through several services, or when a framework encodes a value the code had already encoded.

To read such a string, decode until no escapes remain; Decode repeatedly does that and reports the number of rounds. To fix the cause, find the layer that encodes a second time. A legitimately nested URL, such as a next= or url= parameter holding another URL, needs exactly one extra layer and no more.

Email security gateways are a common source of such nesting. A Microsoft Defender Safe Links URL looks like https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fexample.com%2Freset%3Fid%3D42&data=…; paste it and the parameter table shows the real destination, https://example.com/reset?id=42, without you clicking anything.

Malformed escapes and legacy charsets

A % must be followed by exactly two hex digits. 100%, %zz or a URL cut off mid-escape is an error, and the decoder reports Broken escape at position N. JavaScript’s decodeURIComponent throws URIError: URI malformed in the same cases, while Python’s unquote leaves the sequence as it is.

The other source of errors is the charset. Percent-escapes are bytes, and %E9 alone is not valid UTF-8. Python decodes it as the replacement character, JavaScript throws. With Charset set to Windows-1252 or ISO-8859-1 it decodes to é. Shift_JIS, GBK, EUC-KR, KOI8-R and other legacy charsets are in the same list.

URL decoding in code

decodeURIComponent("a%20b%26c")                   // "a b&c"
new URLSearchParams("q=a+b%2Bc").get("q")          // "a b+c"
from urllib.parse import unquote, unquote_plus, parse_qs
unquote("caf%C3%A9")                     # 'café'
unquote("caf%E9", encoding="latin-1")    # 'café'
unquote_plus("q=a+b%2Bc")                # 'q=a b+c'
parse_qs("q=a+b%2Bc&tag=x&tag=y")        # {'q': ['a b+c'], 'tag': ['x', 'y']}

decodeURIComponent does not turn + into a space; URLSearchParams and unquote_plus do. Pick the one that matches how the string was produced. For encoding, see the URL encoder, and for Base64 that arrived through a URL, the Base64URL decoder.

FAQ

How do I decode a URL-encoded string?

Paste it above; the decoded text appears as you type. In JavaScript use decodeURIComponent(s), in Python urllib.parse.unquote(s), or unquote_plus(s) when + stands for a space.

Why does my decoded URL still contain %20 or %3A?

It was encoded twice. One round turns %2520 into %20; a second round gives the space. Tick Decode repeatedly and the decoder keeps going until no escapes are left, up to five rounds, and says how many it took.

Why does decodeURIComponent throw URI malformed?

Either a % is not followed by two hex digits, as in 100%, or the bytes are not valid UTF-8, as with %E9 from a Windows-1252 system. This decoder points to the exact position, and the Charset option decodes legacy encodings.

Should + be decoded as a space?

In query strings and form bodies, yes, which is why Treat + as space is on by default. In URL paths and in values that may contain Base64, untick it, since there + is a literal plus.