Double Encoding Problems in URLs
Understand double URL encoding: what causes it, how to detect it, and how to fix it. Learn why %2520 appears instead of spaces and how to prevent it.
Character
%25
Encoded
%2525
Detailed Explanation
Double encoding occurs when an already percent-encoded string is encoded again, causing each % in the encoded sequences to be re-encoded as %25. This produces corrupted URLs where, for example, a space (%20) becomes %2520, which decodes to the literal string %20 instead of a space.
How double encoding happens:
Original: "hello world"
First encoding: "hello%20world"
Second encoding: "hello%2520world"
^^ %25 is the encoded %
Decoding once: "hello%20world" (not what you wanted)
Decoding twice: "hello world" (correct, but requires knowing about the double encoding)
Common causes:
- Encoding user input that is already encoded: A URL is pasted into a form field, and the form submission encodes it again
- Framework double-encoding: Some HTTP client libraries encode parameters automatically. If you pre-encode the value, it gets encoded twice
- Redirect chains: Each redirect may re-encode the URL
- Copy-paste from address bars: Browsers display decoded URLs but may copy the encoded form
JavaScript detection and prevention:
// Detect double encoding by looking for %25 in the URL
const isDoubleEncoded = (url) => /%25[0-9A-Fa-f]{2}/.test(url);
// Safe encoding: only encode if not already encoded
function safeEncode(str) {
try {
// If decoding changes the string, it might already be encoded
const decoded = decodeURIComponent(str);
if (decoded !== str) {
// String was already encoded; return as-is
return str;
}
} catch (e) {
// decodeURIComponent threw an error; string is not validly encoded
}
return encodeURIComponent(str);
}
// Example
safeEncode("hello%20world"); // "hello%20world" (not re-encoded)
safeEncode("hello world"); // "hello%20world" (encoded once)
Warning about the detection approach: The safeEncode function above is a heuristic and can produce incorrect results for strings that naturally contain percent signs (like "100%20 discount"). There is no foolproof way to detect whether a string is already encoded. The best practice is to maintain clear encoding boundaries: raw strings go in, encoded strings come out, and encoding happens exactly once at the point where the URL is constructed.
Real-world symptoms:
- URLs containing
%2520(double-encoded space) or%253D(double-encoded equals) - Search queries showing literal
%20in the results - Redirect URLs failing because the target URL is double-encoded
- API errors when parameters contain literal percent sequences
Pitfall: The most insidious form of double encoding happens silently across system boundaries. Service A encodes a URL and passes it to Service B, which encodes it again when embedding it in a redirect. The user sees a broken URL and neither team can reproduce the issue in isolation. Document your encoding contracts between services explicitly.
Use Case
Debugging URL encoding issues in web applications where %2520 appears instead of spaces, or API parameters contain literal percent sequences instead of decoded characters.