Skip to main content
HTML Validation

Bad value for attribute “src” on element “img”: Illegal character in query: “[” is not allowed.

About This HTML Issue

The URL specification (defined by WHATWG and RFC 3986) restricts which characters can appear unencoded in different parts of a URL. Square brackets are reserved characters that have a specific meaning in URLs — they are only permitted in the host portion (to wrap IPv6 addresses like [::1]). In the query string, they must be percent-encoded.

This issue commonly appears when frameworks (especially PHP, Ruby on Rails, or JavaScript libraries) generate URLs with array-style query parameters like ?filter[color]=red. While many browsers and servers are lenient and will interpret these URLs correctly, they are technically invalid according to the URL standard. The W3C validator enforces this rule strictly.

Beyond standards compliance, using unencoded square brackets can cause problems in practice. Some HTTP clients, proxies, or caching layers may reject or mangle URLs containing raw brackets. Percent-encoding these characters ensures your URLs are universally safe and interoperable across all systems.

How to fix it

You have two main approaches:

  1. Percent-encode the brackets. Replace every [ with %5B and every ] with %5D in the URL. This preserves the parameter structure that your server or framework expects, while making the URL valid.

  2. Restructure the query parameters. If your backend allows it, use flat parameter names with dot notation, underscores, or dashes instead of bracket syntax. For example, change size[width] to size_width or size.width.

If you’re generating URLs in JavaScript, the built-in encodeURI() function does not encode square brackets. Use encodeURIComponent() on individual parameter names or values, or manually replace [ and ] after constructing the URL.

Examples

❌ Invalid: unencoded square brackets in query string

<img src="/images/photo.jpg?size[width]=300&size[height]=200" alt="A sample photo">

The literal [ and ] characters in the query string trigger the validation error.

✅ Fixed: percent-encoded brackets

<img src="/images/photo.jpg?size%5Bwidth%5D=300&size%5Bheight%5D=200" alt="A sample photo">

Replacing [ with %5B and ] with %5D makes the URL valid. Most servers and frameworks will decode these automatically and interpret the parameters the same way.

✅ Fixed: flat parameter names without brackets

<img src="/images/photo.jpg?size_width=300&size_height=200" alt="A sample photo">

If you control the server-side logic, you can avoid brackets altogether by using a flat naming convention for your parameters.

❌ Invalid: brackets in more complex query strings

<img
  src="/api/image?filters[type]=jpeg&filters[quality]=80&crop[x]=10&crop[y]=20"
  alt="Processed image">

✅ Fixed: all brackets encoded

<img
  src="/api/image?filters%5Btype%5D=jpeg&filters%5Bquality%5D=80&crop%5Bx%5D=10&crop%5By%5D=20"
  alt="Processed image">

Encoding in JavaScript

If you build image URLs dynamically, handle the encoding in your code:

// Manual replacement approach
const url = "/images/photo.jpg?size[width]=300&size[height]=200";
const safeUrl = url.replace(/\[/g, "%5B").replace(/\]/g, "%5D");
img.src = safeUrl;

// Using URLSearchParams (automatically encodes brackets)
const params = new URLSearchParams();
params.set("size[width]", "300");
params.set("size[height]", "200");
img.src = `/images/photo.jpg?${params.toString()}`;

Both approaches produce a valid, properly encoded URL that will pass W3C validation.

Find issues like this automatically

Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.

Help us improve our guides

Was this guide helpful?

Ready to validate your sites?
Start your free trial today.