About This HTML Issue
The headers attribute creates explicit associations between data cells (td) and header cells (th) in complex tables. This is especially important for tables with irregular structures—such as those with merged cells or multiple header levels—where the browser cannot automatically determine which headers apply to which data cells.
When the validator reports this error, it means one or more IDs referenced in a td‘s headers attribute cannot be matched to any th element with that id in the same table. Common causes include:
-
Typos — A small misspelling in either the
headersvalue or thethelement’sid. -
Missing
id— Thethelement exists but doesn’t have anidattribute assigned. -
Removed or renamed headers — The
thwas deleted or itsidwas changed during refactoring, but thetdstill references the old value. -
Cross-table references — The
thwith the referencedidexists in a different<table>, which is not allowed.
Why this matters
This issue directly impacts accessibility. Screen readers use the headers attribute to announce which header cells are associated with a data cell. When a referenced ID doesn’t resolve to a th in the same table, assistive technology cannot provide this context, making the table confusing or unusable for users who rely on it. Broken headers references also indicate invalid HTML according to the WHATWG HTML specification, which requires that each token in the headers attribute match the id of a th cell in the same table.
How to fix it
-
Locate the
tdelement flagged by the validator and note the ID it references. -
Search the same
<table>for athelement with a matchingid. -
If the
thexists but has noidor a differentid, add or correct theidattribute so it matches. -
If the
thwas removed, either restore it or remove theheadersattribute from thetd. -
Double-check for case sensitivity — HTML
idvalues are case-sensitive, soheaders="Name"does not matchid="name".
Examples
Incorrect: headers references a non-existent ID
The first td references "product", but no th has id="product". The second th has id="cost", but the second td references "price" — a mismatch.
<table>
<tr>
<th>Product</th>
<th id="cost">Price</th>
</tr>
<tr>
<td headers="product">Widget</td>
<td headers="price">$9.99</td>
</tr>
</table>
Correct: each headers value matches a th with the same id
<table>
<tr>
<th id="product">Product</th>
<th id="cost">Price</th>
</tr>
<tr>
<td headers="product">Widget</td>
<td headers="cost">$9.99</td>
</tr>
</table>
Correct: multiple headers on a single td
In complex tables, a data cell may relate to more than one header. List multiple IDs separated by spaces — each one must correspond to a th in the same table.
<table>
<tr>
<th id="region" rowspan="2">Region</th>
<th id="q1" colspan="2">Q1</th>
</tr>
<tr>
<th id="sales">Sales</th>
<th id="returns">Returns</th>
</tr>
<tr>
<td headers="region">North</td>
<td headers="q1 sales">1200</td>
<td headers="q1 returns">45</td>
</tr>
</table>
Tip: simple tables may not need headers at all
For straightforward tables with a single row of column headers, browsers and screen readers can infer the associations automatically. In those cases, you can omit the headers attribute entirely and avoid this class of error:
<table>
<tr>
<th>Product</th>
<th>Price</th>
</tr>
<tr>
<td>Widget</td>
<td>$9.99</td>
</tr>
</table>
Reserve the headers attribute for complex tables where automatic association is insufficient — such as tables with cells that span multiple rows or columns, or tables with headers in both rows and columns.
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.