# Bad value for attribute “href” on element “a”: Illegal character in fragment: “#” is not allowed.

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

In a URL, the `#` character has a special role: it acts as the delimiter that separates the main URL from the **fragment identifier**. The fragment typically points to a specific section or element within the target document, often corresponding to an element's `id` attribute. Because `#` serves this reserved purpose, it cannot appear more than once in its raw form within a URL. When the validator encounters something like `##pricing` or `section#one#two`, it flags the extra `#` characters as illegal.

This issue usually arises from one of these common scenarios:

- **Typos** — accidentally typing `##` instead of `#`.
- **String concatenation bugs** — building URLs programmatically where a `#` is included both in the base URL and prepended to the fragment value.
- **Copy-paste errors** — duplicating the `#` when copying URLs from browser address bars or other sources.
- **Literal `#` intended in fragment** — if you genuinely need a `#` symbol within the fragment text, it must be percent-encoded as `%23`.

This matters because browsers may handle malformed URLs inconsistently. Some browsers silently strip the extra `#`, while others may fail to navigate to the intended fragment. Malformed URLs also cause problems for assistive technologies, web crawlers, and any tooling that parses links. Keeping your URLs well-formed ensures predictable behavior across all user agents and complies with the [URL Standard](https://url.spec.whatwg.org/) and HTML specification.

## Examples

### Incorrect: duplicate `#` in the URL

The double `##` makes the fragment identifier invalid:

```html
<a href="https://example.com/faqs##pricing">Pricing</a>
```

### Correct: single `#` delimiter

Remove the extra `#` so that `pricing` is the fragment:

```html
<a href="https://example.com/faqs#pricing">Pricing</a>
```

### Incorrect: extra `#` inside the fragment

Here, the fragment portion `overview#details` contains a raw `#`, which is not allowed:

```html
<a href="/docs#overview#details">Details</a>
```

### Correct: percent-encode the literal `#`

If you truly need a `#` as part of the fragment text, encode it as `%23`:

```html
<a href="/docs#overview%23details">Details</a>
```

In most cases though, this pattern suggests the URL structure should be rethought. A cleaner approach is to link directly to the intended fragment:

```html
<a href="/docs#details">Details</a>
```

### Incorrect: programmatic concatenation error

A common bug in templates or JavaScript is prepending `#` when the variable already includes it:

```html
<!-- If defined as defined as fragment = "#pricing", this produces a double ## -->
<a href="https://example.com/faqs#pricing">Pricing</a>
```

### Correct: ensure only one `#` is present

Make sure either the base URL or the fragment variable includes the `#`, but not both:

```html
<a href="https://example.com/faqs#pricing">Pricing</a>
```

### Fragment-only links

Fragment-only links (links to sections within the same page) follow the same rule — only one `#`:

```html
<!-- Incorrect -->
<a href="##contact">Contact Us</a>

<!-- Correct -->
<a href="#contact">Contact Us</a>
```
