Debugging7 min read

How to Fix "URI Malformed" Errors in JavaScript

Troubleshoot and fix the common "URIError: URI malformed" error in JavaScript with practical solutions.

Understanding the URIError: URI Malformed Error

The URIError: URI malformed error occurs in JavaScript when you try to decode a string that contains invalid percent-encoded sequences. This error is thrown by decodeURI() or decodeURIComponent() when they encounter a malformed encoded character.

Common Causes

1. Lone Percent Signs

A percent sign (%) that is not followed by exactly two hexadecimal digits is invalid. For example, %, %G, or %2 (incomplete) will all cause this error.

// These will throw URIError
decodeURIComponent('%');        // Lone %
decodeURIComponent('%2');       // Incomplete sequence
decodeURIComponent('%GH');      // Invalid hex digits
decodeURIComponent('100%');     // % at end without hex digits

2. Invalid UTF-8 Sequences

When the percent-encoded bytes do not form a valid UTF-8 character sequence, the decoder cannot convert them to a string. This can happen when data is corrupted or was encoded using a different character encoding.

3. Double Encoding

Double encoding occurs when an already-encoded string is encoded again. For example,%20 (encoded space) gets encoded to %2520. When you try to decode the original string, the sequences may be invalid.

How to Fix It

Solution 1: Use try-catch

function safeDecode(str) {
  try {
    return decodeURIComponent(str);
  } catch (e) {
    // Return the original string if decoding fails
    console.warn('Failed to decode:', str, e.message);
    return str;
  }
}

Solution 2: Validate Before Decoding

function isValidEncodedURI(str) {
  try {
    decodeURIComponent(str);
    return true;
  } catch {
    return false;
  }
}

function fixMalformedURI(str) {
  // Replace lone % with %25 (encoded percent)
  return str.replace(/%(?![0-9A-Fa-f]{2})/g, '%25');
}

Solution 3: Prevent Double Encoding

function smartEncode(str) {
  // First try to decode - if it succeeds, the string
  // is already encoded
  try {
    const decoded = decodeURIComponent(str);
    // If decoding changed the string, it was encoded
    if (decoded !== str) {
      return str; // Already encoded, return as-is
    }
  } catch {
    // Not valid encoded string, encode it
  }
  return encodeURIComponent(str);
}

Prevention Best Practices

  • Always use try-catch when decoding user-provided or external URLs
  • Validate URLs before processing them
  • Be careful not to double-encode values
  • Use the URL and URLSearchParams APIs when possible -- they handle encoding correctly
  • Sanitize query string values before encoding
  • Log malformed URLs for debugging

Related Articles

Try Our Free Tools