# IDs used in ARIA and label associations must be unique to avoid broken references.

> Canonical HTML version: https://rocketvalidator.com/accessibility-validation/accesslint/0.16/labels-and-names/duplicate-id-aria
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

When multiple elements on a page share the same `id` attribute, any ARIA or label association that references that `id` will only resolve to the first matching element in the DOM. This means the intended target of an `aria-labelledby`, `aria-describedby`, `aria-controls`, or `label[for]` reference may not be reached at all. The result is controls that lack accessible names, descriptions that point to the wrong content, or relationships between elements that silently break.

Screen reader users are the most directly affected. If a form input's `label[for]` attribute points to a duplicated `id`, the screen reader may announce the label text from an unrelated element, or announce nothing at all. The same applies to `aria-labelledby` and `aria-describedby`: when the referenced `id` appears more than once, browsers return the first element with that `id`, ignoring any subsequent matches. A user who relies on the announced name or description of a control will receive incorrect or missing information, making the interface difficult or impossible to use.

This rule maps to WCAG success criterion 4.1.2 (Name, Role, Value) at Level A. That criterion requires that all user interface components have names and roles that can be programmatically determined. When a duplicate `id` breaks the reference between a label and its control, the control's name cannot be programmatically determined, and the page fails this criterion.

## How to fix it

The fix depends on your specific page structure. Audit the document for duplicate `id` values and make each one unique. A few common scenarios:

- A template or component is rendered multiple times on the same page, producing identical `id` values each time. Append a unique suffix (such as an index or a generated identifier) to each instance.
- A copy-paste error has introduced the same `id` on two unrelated elements. Rename one of them.
- A `label[for]` or `aria-labelledby` reference was written to target one specific element, but a second element with the same `id` was added later. Update either the duplicate `id` or the referencing attribute so the association is unambiguous.

After making changes, verify that every `aria-labelledby`, `aria-describedby`, `aria-controls`, and `label[for]` attribute still resolves to the correct, unique element.

## Examples

### Duplicate `id` breaking a label association

In this example, two inputs share the `id` value `"email"`. The second label's `for` attribute resolves to the first input, leaving the second input without an accessible name.

```html
<label for="email">Personal email</label>
<input type="email" id="email">

<!-- Later in the same page -->
<label for="email">Work email</label>
<input type="email" id="email">
```

### Fixed: unique `id` values

Each input has a distinct `id`, so both labels correctly reference their respective inputs.

```html
<label for="personal-email">Personal email</label>
<input type="email" id="personal-email">

<label for="work-email">Work email</label>
<input type="email" id="work-email">
```

### Duplicate `id` breaking `aria-describedby`

Here, two elements share the `id` `"hint"`. The second input's `aria-describedby` resolves to the first paragraph, so the user hears the wrong hint text.

```html
<p id="hint">Enter your first name.</p>
<input type="text" aria-label="First name" aria-describedby="hint">

<p id="hint">Enter your last name.</p>
<input type="text" aria-label="Last name" aria-describedby="hint">
```

### Fixed: unique `id` values for descriptions

```html
<p id="first-name-hint">Enter your first name.</p>
<input type="text" aria-label="First name" aria-describedby="first-name-hint">

<p id="last-name-hint">Enter your last name.</p>
<input type="text" aria-label="Last name" aria-describedby="last-name-hint">
```

### Duplicate `id` in a repeated component

When rendering the same component multiple times (for example, in a loop), each instance must produce unique `id` values.

```html
<!-- Two instances of a toggle component with the same id -->
<button aria-controls="panel">Settings</button>
<div id="panel">Settings content</div>

<button aria-controls="panel">Notifications</button>
<div id="panel">Notifications content</div>
```

### Fixed: scoped `id` values per instance

```html
<button aria-controls="settings-panel">Settings</button>
<div id="settings-panel">Settings content</div>

<button aria-controls="notifications-panel">Notifications</button>
<div id="notifications-panel">Notifications content</div>
```
