url debugging web-development javascript encoding

Solving 'URIError: URI malformed' and common URL Errors

A comprehensive guide to fixing URL errors like 'URI malformed', 'invalid URL', and percent-encoding issues. Learn the difference between encodeURI and encodeURIComponent.

2026-04-11 Use This Tool

Solving "URIError: URI malformed" and common URL Errors: A Complete Guide

URLs (Uniform Resource Locators) are the addresses of the web. While they seem simple, they have strict rules about which characters are allowed. When these rules are broken, you encounter errors like URIError: URI malformed, TypeError: Failed to construct 'URL': Invalid URL, or simply a broken link that leads to a 404.

In this guide, we will dive into the most common URL-related errors and how to solve them in JavaScript and other environments.


1. Common URL Error Messages

Depending on what you are doing, you might encounter these errors:

  • JavaScript (decodeURIComponent): URIError: URI malformed
  • JavaScript (new URL()): TypeError: Failed to construct 'URL': Invalid URL
  • Python (urllib): ValueError: Invalid URL
  • Java (URLDecoder): java.lang.IllegalArgumentException: URLDecoder: Incomplete % sequence

2. Top Causes and Solutions

2.1 "URIError: URI malformed"

This error occurs in JavaScript when decodeURI() or decodeURIComponent() encounters a percent-encoding sequence that is invalid. This usually happens if a % sign is not followed by two hexadecimal digits, or if the sequence represents an invalid UTF-8 character.

The Error:

decodeURIComponent("%") // URIError: URI malformed
decodeURIComponent("%E0%A4%A") // URIError: URI malformed (Incomplete)

The Solution:

  1. Escape single % signs: If your string contains literal % signs that are not part of an encoded sequence, you must escape them as %25.
  2. Check for truncation: Ensure the URL wasn't cut off mid-sequence (e.g., at the end of a database field or a long query parameter).
  3. Use a Try-Catch: Always wrap decoding in a try-catch block.
function safeDecode(str) {
  try {
    return decodeURIComponent(str);
  } catch (e) {
    console.error("Malformed URI:", str);
    return str; // Return raw string if decoding fails
  }
}

2.2 encodeURI vs. encodeURIComponent

A common mistake is using the wrong encoding function, leading to "invalid URL" errors when the server receives the request.

  • encodeURI(): Used for the entire URL. it does NOT encode characters that have special meaning in a URL structure (like :, /, ?, #, &, =).
  • encodeURIComponent(): Used for individual parameters (like a search query or a filename). It encodes everything except a few basic characters.

The Mistake:

const url = "https://example.com/search?q=" + encodeURI("blue/green");
// Result: https://example.com/search?q=blue/green (The / breaks the parameter)

The Correct Way:

const url = "https://example.com/search?q=" + encodeURIComponent("blue/green");
// Result: https://example.com/search?q=blue%2Fgreen (Correct!)

2.3 "TypeError: Invalid URL"

This happens when you pass a string to the URL constructor that isn't a valid absolute URL (e.g., it's missing the protocol like https://).

The Error:

new URL("www.google.com") // TypeError: Invalid URL

The Solution: Ensure the URL is absolute or provide a base URL as the second argument.

new URL("https://www.google.com") // Correct
new URL("/path", "https://example.com") // Correct

2.4 Percent Encoding Errors (Spaces and Special Characters)

URLs cannot contain spaces. While some browsers automatically convert spaces to %20 or +, relying on this is dangerous.

The Solution: Always encode dynamic data.

  • Space -> %20 (Standard)
  • Space -> + (Only valid in query strings, like ?q=hello+world)

3. Advanced Troubleshooting

3.1 Double Encoding

If you encode a string twice, it becomes a mess. For example, space becomes %20, then %2520. Solution: Track where encoding happens. Only encode data once, right before appending it to the URL.

3.2 Non-UTF-8 Encodings

The modern web uses UTF-8. If you encounter an old system using GBK or Latin1 for URL parameters, decodeURIComponent will fail or produce "mojibake" (garbage text). Solution: You may need a library like iconv-lite to handle legacy encodings before processing the URL.


4. Prevention and Best Practices

  1. Use the URL API: Instead of manual string concatenation, use the built-in URL and URLSearchParams APIs. They handle encoding automatically and correctly.
  2. Be Specific: Use encodeURIComponent for parameter values and encodeURI for the base path.
  3. Sanitize Input: If users are providing URLs, validate them using the URL constructor in a try-catch block.
function isValidUrl(string) {
  try {
    new URL(string);
    return true;
  } catch (_) {
    return false;  
  }
}

5. FAQ: Frequently Asked Questions

Q: What is the difference between %20 and + for spaces?

A: %20 is the standard encoding for a space character in any part of a URI. + is a legacy convention specifically for query parameters (application/x-www-form-urlencoded). Use %20 for maximum compatibility.

Q: Why do I see %25 in my URL?

A: %25 is the encoded version of the % character itself. This usually happens when a URL that was already encoded is encoded again (double encoding).

Q: How do I handle URLs with Emoji or non-Latin characters?

A: Always use encodeURIComponent. It correctly converts Unicode characters into a sequence of UTF-8 bytes and then percent-encodes each byte.


6. Quick Check Tool

Struggling with a malformed URL? Use our URL Encoder & Decoder. It can:

  • Instantly validate if a URL is well-formed.
  • Compare encodeURI and encodeURIComponent results.
  • Safely decode complex query strings.
  • Handle Internationalized Domain Names (IDN).

Related Errors