Skip to content

URL Decoder

Runs 100% in your browser — nothing is uploaded, nothing is stored.

Decoding happens entirely in your browser.

Percent-encoded values are everywhere and almost never meant to be read as-is: a redirect parameter holding a whole URL, an email tracking link, a signed asset path with an expiry timestamp buried in it. This decoder turns them back into something legible and, when the input is a URL, breaks out its parts — scheme, host, path, query and fragment — plus each query parameter as a key and value pair.

It also handles the two cases that trip up strict decoders: double-encoded values, and malformed escapes that would otherwise cause the whole decode to fail and return nothing.

How to use this tool

  1. Paste the encoded URL or text into the input box.
  2. Click Decode. The readable result appears below, and if the input is a recognised URL its parts are listed underneath.
  3. Tick Decode repeatedly when a value looks double-encoded — the common sign is %2520 where you expected a space.
  4. Tick Treat + as space only for form-encoded query strings. In a path, a plus sign is a literal plus and should stay one.
  5. Load sample fills in a fully encoded URL with a query string, so you can see the parts breakdown without hunting for an example.

The plus sign ambiguity, and why it is an option rather than a default

Two different standards assign a meaning to + in a URL, and they disagree.

RFC 3986, which defines URL syntax, treats + as a literal plus sign. It is a valid character in a path and in a query, and it means what it looks like.

The form-encoding convention application/x-www-form-urlencoded, which is what an HTML form submits, repurposes + as a shorthand for a space. This is a historical artefact of form handling, and it applies only to the body of a form submission and to query strings produced by one.

The problem is that you often cannot tell which convention produced a given string. A query string in a link might have come from a form, or might have been built by hand or by a library that used %20. Deciding wrongly corrupts the value in one direction or the other:

  • Decode a literal plus as a space, and a phone number +1-555-0100 becomes 1-555-0100, a base64 fragment loses a character, and a mathematics query reshapes itself.
  • Leave a form-encoded plus alone, and salt+and+pepper stays as three words joined by plus signs rather than becoming a phrase.

The honest answer is that this cannot be inferred from the string alone, so the tool does not guess. The option is off by default, which is the conservative choice: leave a plus as a plus unless you have reason to believe the value came from a form.

Double encoding, and how to recognise it

Encoding is not idempotent. Encode an already-encoded value and every percent sign gets escaped again, so %20 becomes %2520 — the % is itself encoded as %25, followed by the original digits.

This happens in practice for understandable reasons. A redirect parameter contains a URL, so that inner URL gets encoded once as a value. If the resulting outer URL is then placed inside another URL, or passed through a system that encodes query parameters generically, it gets encoded a second time. Nothing is broken at any single step; the layers simply stack.

The signature is the string %25, which is an encoded percent sign. Seeing it is a strong signal that at least one more decode is waiting:

  • %2520 — decode once to get %20, decode twice to get a space.
  • %253A%252F%252F — decode twice to get ://, the mark of a URL embedded in a URL.
  • %2526 — decode twice to get &, a parameter separator that was encoded as data and then encoded again.

Ticking Decode repeatedly keeps applying the decode until the output stops changing, which resolves any depth of nesting without you having to count layers. It is safe to leave on for genuinely single-encoded input, because the second pass finds nothing left to decode and returns the same string.

Malformed input, and why strict decoders return nothing

The standard decode function throws on invalid input and returns no output at all. That is unhelpful when you are trying to read a value you received from somewhere else and you have no control over its quality.

Two kinds of malformed escape cause this:

  • A lone percent sign. A % not followed by two hexadecimal digits is not a valid escape. This is common in strings where a literal percent is genuinely part of the data — a discount label, a format string, a URL that contains % without encoding it as %25.
  • A truncated escape. %2 at the end of the string, or %GG where the digits are not hexadecimal. Both mean something was cut off or mis-typed.

This tool decodes as far as it can and tells you that part of the input was left untouched, so you still see most of the value rather than an empty box. That is deliberately the opposite of the strict behaviour, because the common situation is forensic — you have a malformed string and want to extract as much meaning as possible from it, not fail cleanly.

If the output still contains percent signs after decoding, there are two explanations. Either the input was encoded more than once, in which case turn on Decode repeatedly, or those percent signs are literal characters that were never escapes. The correct encoding for a literal percent is %25, so a well-formed URL containing a percentage sign should decode cleanly.

Reading a URL as parts rather than as a string

When the input is a URL, the tool breaks it into its components, and that breakdown is often more useful than the decoded text on its own.

The pieces are worth knowing by name, because most debugging conversations use them:

  • Scheme — https, mailto, data. Determines how the rest is interpreted.
  • Host — the domain, and with it the security boundary. A redirect parameter whose host differs from the one you expect is worth noticing.
  • Path — the resource within that host.
  • Query — everything after the question mark, as key-value pairs.
  • Fragment — everything after a hash. This is never sent to the server, which is why single-page applications use it for routing state.

Seeing the parameters split out as decoded pairs is the fastest way to answer questions like which tracking parameters a marketing link actually carries, whether the redirect parameter points somewhere you expect, and what the expiry timestamp in a signed URL actually is.

To go the other direction — turning a value into a safe URL component — the URL Encoder offers query, path and full-URL modes so the encoding matches where the value is going.

Decoding decisions and when to make them

You are looking atDo thisBecause
%20 between wordsDecode onceA single layer of encoding, the ordinary case
%2520 or %253ATick Decode repeatedlyThe percent sign was itself encoded, so a layer is nested
salt+and+pepper in a queryTick Treat + as spaceA form-encoded value, where plus means space
+1-555-0100 as a parameter valueLeave the option offA literal plus, which would be destroyed by the form convention
A base64 value with a plus in itLeave the option offBase64 plus is data; interpreting it as a space corrupts the payload
A lone percent sign with no digits after itDecode anywayThe tool decodes what it can and reports the part it left alone
A shortener link you want to followDecode, then open it yourselfThis tool makes no network request and never follows a redirect

Frequently asked questions

When should + be treated as a space?
Only in an application/x-www-form-urlencoded query string, which is what HTML forms submit by default. In a path component a + genuinely means a plus sign, so decoding it as a space would corrupt the value. That is why the option is off by default.
What does "decode repeatedly" do?
It keeps decoding until the result stops changing. This fixes double-encoded values such as %2520, where the first pass yields %20 and only the second gives a space. It is common in links that were encoded once before being placed in a query string and again afterwards.
What happens if the input is malformed?
A lone percent or a truncated escape such as %2 makes a strict decoder throw and return nothing at all. This tool decodes as far as it can and tells you that part of the input was left untouched, so you can still see most of the value.
Why does the output still contain % characters?
Either the input was encoded more than once — turn on Decode repeatedly — or those percent signs are part of the original text and were never escapes. A literal percent sign should have been encoded as %25 by whoever built the URL.
Is this the same as unshortening a link?
No. This only reverses percent-encoding; it performs no network request and does not follow redirects. What you see is what was literally in the string, which is also why it is safe to paste a link you do not trust.
Can it decode a URL that has been encoded several times?
Yes, with Decode repeatedly switched on. It keeps applying the decode until the string stops changing, so any depth of nesting resolves without you counting layers. It is safe to leave on for single-encoded input.
Why do some Chinese characters decode into three escapes?
Because percent-encoding works on bytes, not characters. Most Chinese characters occupy three bytes in UTF-8, so each produces three percent-escapes. Emoji occupy four bytes and produce four. The decoded output is the original text, correctly reassembled.
Does it validate that the URL is well formed?
It parses the URL into components and reports what it finds, but it is not a validator. A URL that decodes and splits into parts is structurally recognisable, not necessarily valid or safe, and nothing here checks whether the host resolves or the path exists.
Is the URL sent anywhere when I decode it?
No. Decoding is a pure string operation in the browser with no network request of any kind, so a link containing a token or an internal hostname is safe to inspect here.
Scroll to Top