( Robust / WCAG 4.1.2 )

ARIA attribute is prohibited for this role

SeriousLevel AWCAG 4.1.2 — Name, Role, Value

What is this issue?

An element has an ARIA naming or describing attribute set, but its role, the ARIA role the specification assigns as prohibiting it, explicitly forbids that attribute from being used at all. This is distinct from an attribute simply missing from a role’s supported list: a prohibited attribute is one the specification names outright as never valid on that role, no matter the value.

The roles most commonly involved are presentation and none, which exist specifically to strip an element of its semantics for assistive technology, plus generic (the implicit role most bare <div> and <span> elements resolve to) and several inline text-semantic roles like code, strong, emphasis, insertion, and deletion. All of these are defined by the spec as carrying no accessible name, so an aria-label on any of them contradicts the role’s own definition.

Why does this matter?

role="presentation" and role="none" are a deliberate instruction: “assistive technology should treat this element as if it isn’t part of the interface at all.” Adding aria-label to an element with that role sends a contradictory signal (strip my semantics, but also announce a name for me), and the specification resolves the conflict by dropping the name, not by keeping it.

The result is a naming attribute a developer wrote, tested visually, and shipped, that never reaches a single assistive technology user. This is most damaging on close buttons, icon-only controls, and small interactive elements where a <span> or <div> was reused from a decorative pattern and then given interactive behavior without also being given a real, name-supporting role: the visual icon works, the click handler works, and the accessible name is silently discarded.

Who is affected?

  • Screen reader users: never hear the label text at all, since it’s stripped before the accessibility tree is built, leaving an icon-only control announced with no name or a generic fallback like “button” with no further context.

What users experience

Wei uses VoiceOver on his MacBook to close a promotional overlay on a news site. The close control is a <span aria-label="Close">×</span> with a click handler attached, but a bare <span> resolves to the generic role, which the ARIA specification prohibits from carrying a name. VoiceOver announces it only as “clickable text, ×” with no name at all. Wei has to guess from the visual “×” symbol and its position in the corner of the overlay that this is a close control, something a sighted user recognizes instantly but he has to infer from position and past experience with similar overlays.

How do I fix it?

Give the element a role that supports naming (most reliably, use a native <button>) instead of trying to name an element whose role forbids it. This works because a <button> carries the button role implicitly, and button is one of the many roles that fully supports aria-label, so the same attribute that was silently dropped on a <span> starts working the moment the underlying element changes.

If you genuinely need to keep a non-interactive <div> or <span> and it needs a name, assign it an ARIA role that supports naming, such as role="img" for a meaningful icon or role="group" for a labeled cluster of related content, rather than leaving it with an implicit generic role. If the element is truly decorative and doesn’t need a name at all, drop the naming attribute and use aria-hidden="true" instead, so its lack of a name is an intentional, correctly-signaled choice rather than a silently dropped one.

Code Examples

Before
<span class="icon-close" aria-label="Close">×</span>
After
<!-- Method 1: use a real button, which supports naming (broadest support) -->
<button class="icon-close" aria-label="Close">×</button>

<!-- Method 2: keep the div/span, but give it a role that allows a name -->
<div class="icon-close" role="img" aria-label="Close">×</div>

Method 1 switches the element type entirely, which is the more reliable fix whenever the control is genuinely interactive: a <button> gets keyboard focus, Enter/Space activation, and a naming-capable role automatically, none of which a styled <span> provides on its own. Method 2 keeps the original element but assigns it role="img", a role that does support aria-label, appropriate only if the element is not meant to be a real interactive control (it would still need separate keyboard handling to be clickable).

Common Mistakes

Mistake: “aria-label works on any element, so it doesn’t matter what role I use.” aria-label is a globally-supported attribute on most roles, which makes the small set of roles that explicitly prohibit it easy to overlook. presentation, none, and generic are the exceptions, not the rule, but they’re also some of the most common implicit roles on plain <div> and <span> elements, which is exactly why this mistake happens so often.

Mistake: “The label text is right there in the attribute, so screen readers must read it.” The browser builds the accessibility tree from the DOM before assistive technology ever sees it, and a prohibited attribute is dropped during that build step; the text exists in the HTML source but never survives translation into anything a screen reader queries.

Mistake: “I’ll add role=‘presentation’ AND aria-label, so it’s both hidden and named, extra safe.” The two instructions directly conflict, and the specification resolves the conflict in favor of presentation winning: the name is discarded, not preserved as a fallback. Stacking contradictory attributes doesn’t create redundancy; it just guarantees the naming attribute never has any effect.

How RedFlag Detects This

Automated: axe-core rule, runs on every scan. RedFlag calls axe-core’s aria-prohibited-attr rule as part of every scan, restricted to the WCAG 2.0/2.1/2.2 A and AA rule set. The rule checks each element’s resolved role, explicit or implicit, against the WAI-ARIA specification’s list of roles that explicitly prohibit naming and describing attributes, and flags aria-label, aria-labelledby, or aria-describedby present on any of them.

False negative: the rule can’t tell whether removing the prohibited attribute was the right call versus whether the element genuinely needed a real, name-supporting role instead: a flagged element that gets its aria-label deleted rather than being given a proper role still ends up unnamed, just without a scan violation anymore. False positive: none typical for this check, since the list of naming-prohibited roles is fixed and the attribute check is binary. Manual step: for every flagged element, decide whether it needs to be identifiable to assistive technology at all; if it does, give it a real role that supports naming rather than only deleting the attribute to silence the scan.

Manual Testing

  1. Open the page in Chrome or Firefox with NVDA or VoiceOver running.
  2. Tab to or navigate by element to every icon-only or unlabeled-looking control (close buttons, icon toggles, small clickable graphics).
  3. Listen for an announced name. It should describe the control’s purpose (“Close,” “Search”), not just its role or nothing at all.
  4. If a control announces no name despite having visible label text or an aria-label in the markup, check whether its role (explicit or implicit) is one that prohibits naming.
  5. Open the browser’s accessibility inspector (Chrome DevTools → Elements → Accessibility pane) and confirm the “Name” property is populated; a blank name on an element you wrote aria-label for is the signature of this failure.

4.1.2 Name, Role, Value: Every interface component must expose a name to assistive technology when one is needed to identify its purpose. An attribute prohibited by the element’s own role fails this criterion in the most literal way: the name a developer intended never reaches the accessibility tree at all.

ARIA attribute is not allowed for this role covers the broader, related failure of a role-specific state or property missing from a role’s supported list; this rule is the narrower, stricter case specifically about naming and describing attributes on roles that forbid them outright.

ARIA role is invalid is the prerequisite check this rule builds on: a genuinely invalid role produces a different failure than a valid role that simply prohibits the attribute you used.

ARIA attribute is not valid for the current role value covers attributes that are conditionally valid depending on another attribute’s state, a different mechanism from an outright, unconditional prohibition.

Element uses a deprecated ARIA role and ARIA attribute name is not valid commonly co-occur with this rule in the same component, since all three stem from the same root cause: ARIA added to markup without checking the spec’s role-specific rules first.

References

Frequently asked questions

Why would ARIA ever prohibit a naming attribute like aria-label?

Because some roles are defined to carry no semantic meaning at all, and a name implies meaning. role="presentation" and role="none" exist specifically to strip an element's semantics for assistive technology, so giving that same element a name would contradict the role's own purpose.

Does this rule only apply to presentation and none roles?

No. The WAI-ARIA specification also prohibits naming attributes on several roles used for inline text semantics, such as code, strong, emphasis, insertion, and deletion, plus the generic role most plain divs and spans resolve to when they carry no other role.

What is the difference between aria-prohibited-attr and aria-allowed-attr?

aria-allowed-attr checks whether a role-specific state or property, like aria-checked, is on that role's supported list. aria-prohibited-attr checks a narrower, stricter case: roles that explicitly forbid otherwise-global naming and describing attributes, like aria-label and aria-describedby, that would normally work almost anywhere.

If I need to label a decorative element, how should I do it instead?

You generally should not label a decorative element at all. If it needs to be hidden from assistive technology entirely, use aria-hidden="true" instead of trying to name it. If it turns out to carry real meaning after all, give it a genuine semantic role first, then name that role.

Does a prohibited attribute cause an error in the browser console?

No. The browser silently drops the prohibited attribute from the accessibility tree without logging a warning or error anywhere a developer would normally see it, which is exactly why this class of bug tends to go unnoticed until an automated accessibility scan or a screen reader user reports it.