# Bad value X for attribute “href” on element “link”: Illegal character in query

> Canonical HTML version: https://rocketvalidator.com/html-validation/bad-value-x-for-attribute-href-on-element-link-illegal-character-in-query
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

URLs used in HTML attributes must follow the [URL Living Standard](https://url.spec.whatwg.org/), which defines a specific set of characters that are allowed in each part of a URL. The query component of a URL — everything after the `?` — permits most printable ASCII characters, but certain characters are still considered illegal and must be percent-encoded. When the W3C validator encounters one of these forbidden characters in the `href` of a `<link>` element, it raises this error.

Common characters that trigger this issue include:

| Character | Percent-encoded |
|-----------|-----------------|
| `|` (pipe) | `%7C` |
| `[` (left bracket) | `%5B` |
| `]` (right bracket) | `%5D` |
| `{` (left brace) | `%7B` |
| `}` (right brace) | `%7D` |
| `^` (caret) | `%5E` |
| `` ` `` (backtick) | `%60` |
| (space) | `%20` |

## Why this matters

While many modern browsers are lenient and will silently fix malformed URLs, relying on this behavior is risky. Invalid URLs can cause problems in several ways:

- **Inconsistent browser behavior**: Not all user agents handle illegal characters the same way, which can lead to broken stylesheets or resources failing to load.
- **Interoperability issues**: Proxies, CDNs, and other intermediaries may reject or mangle URLs with illegal characters.
- **Standards compliance**: Valid HTML requires valid URLs in attributes. An illegal character in the `href` makes the entire document non-conforming.
- **Copy-paste and sharing reliability**: Malformed URLs are more likely to break when shared across systems, emails, or documentation.

## How to fix it

Identify the illegal characters in your URL's query string and replace each one with its percent-encoded equivalent. If you're generating URLs programmatically, use a proper URL encoding function (e.g., `encodeURIComponent()` in JavaScript, `urlencode()` in PHP, or `urllib.parse.quote()` in Python) to ensure all special characters are encoded correctly.

## Examples

### ❌ Illegal pipe character in the query string

This is a common pattern seen with Google Fonts URLs that use `|` to separate font families:

```html
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans|Roboto">
```

### ✅ Pipe character percent-encoded

```html
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans%7CRoboto">
```

### ❌ Square brackets in the query string

Some APIs or frameworks use bracket notation in query parameters:

```html
<link rel="stylesheet" href="https://example.com/styles?themes[]=dark&themes[]=compact">
```

### ✅ Square brackets percent-encoded

```html
<link rel="stylesheet" href="https://example.com/styles?themes%5B%5D=dark&themes%5B%5D=compact">
```

### ❌ Space character in the query string

```html
<link rel="stylesheet" href="https://example.com/css?file=my styles.css">
```

### ✅ Space character percent-encoded

```html
<link rel="stylesheet" href="https://example.com/css?file=my%20styles.css">
```

Note that for Google Fonts specifically, the modern API (v2) uses a different URL format that avoids the pipe character altogether. Where possible, consider updating to the latest version of an API rather than just encoding the old URL.
