Matterhorn 15-001 · PDF/UA-1 UA1:7.5-1
Row headers in PDF tables: first column tagged TD, not TH
The leftmost (or, in RTL, rightmost) cell of each row labels the row but is tagged TD instead of TH.
The condition, as the protocol states it. “A row has a header cell, but that header cell is not tagged as a header.”
Matterhorn Protocol 1.1, checkpoint 15, index 15-001, section UA1:7.5-1. The protocol marks this as requiring human judgement.
What a screen reader actually does
Moving down a column, the reader cannot announce which row you are in — you hear values with no labels.
What the condition is about
A data table usually has two kinds of label: the header row across the top, saying what each column is, and the first cell of each row, saying what the row is. In a tagged PDF both should be header cells, <TH>, each with a /Scope that says which direction it heads.
The failure is a table where the header row was done and the header column was not:
/Table
├── /TR TH "Region" (Column) TH "2025" (Column) TH "2026" (Column)
├── /TR TD "North" TD "120" TD "135"
├── /TR TD "South" TD "98" TD "104"
└── /TR TD "East" TD "77" TD "81"
“North”, “South” and “East” label their rows, and are tagged as data. Fixed, each is a header with a scope:
├── /TR TH "North" /A << /O /Table /Scope /Row >> TD "120" TD "135"
What the user hears
Screen readers in table mode typically announce the header that changes as you move. Moving across a row, the column changes, so the reader says 2026, 135. Moving down a column, it is the row that changes — and with no header cell in the row there is nothing to say but the values: 135, 104, 81. Which region each number belongs to has to be remembered from somewhere else.
With the row headers tagged, the same move gives South, 104 and East, 81. On a table of three rows that is a convenience. On a table of forty rows read cell by cell it is the difference between using the table and giving up on it.
Where it comes from
Header rows are the setting authoring tools ask about. Whether a first column of labels comes through as header cells depends on the producer, and when it does not, nothing on the printed page looks any different.
Tables tagged in Acrobat. Adobe’s Reading Order tool page says of its Table Editor that it analyses a table into components “however, you must check and correct some of these tags manually”.
Taggart’s own auto-tagger. When it proposes a table on an untagged page, it makes the first row column headers and every other cell a <TD>. A table it builds whose first column labels the rows arrives with this finding.
How to check it free
Acrobat Pro’s Tags panel. Expand the <Table>, then each <TR>, and look at the first cell. A <TD> holding a label is the condition. Adobe’s checklist for table structure — rows containing <TH> or <TD> cells, inside <THead>, <TBody> and <TFoot> where used — is in Edit document structure with the Content and Tags panels, under Correct table tags with the Tags panel.
Acrobat’s Accessibility Checker has table rules for Rows, TH and TD, Headers and Regularity, plus an optional Summary. Headers, as Adobe describes it, asks that a table has a header at all. None of them asks whether the first column should be headers too.
A screen reader. Enter the table and move down a column. If you hear values with no row label, look at the first column’s tags.
No validator decides this one. The Matterhorn Protocol marks it as a human check, because only a reader can tell that a column labels rows.
How to fix it free, in Acrobat Pro
Changing the cell type is documented by Adobe:
- In the Tags panel, expand the
<Table>and the<TR>, and select the first<TD>. - Options → Properties, choose TH from the Type menu, and click Close.
- Repeat for each row.
The cells then need /Scope /Row. Adobe documents the attribute editor for this kind of table attribute only for ColSpan and RowSpan — select the cell → Properties → Tag panel → Edit Attribute Objects, create an attribute object with its Layout value changed to Table, then New Item for the key. Scope is a key in the same table attribute object, with the value Row. Adobe does not document that case itself, so if the dialog does not offer a name-type value, leave Scope out: a <TH> without it is 15-003, which Taggart repairs mechanically (below).
Upstream is still the better fix: mark the header column in the authoring tool if it can, and re-export. See Tag tables correctly.
What Taggart does
Taggart applies a heuristic and reports one finding per table, not per cell. A table is reported when it has at least three rows, it has a header row (or a <TH> among its rows’ first cells), and every body row starts with a <TD>:
Every row of this 4-row table starts with a
<TD>. If the first cell of each row labels that row it should be a<TH>with /Scope /Row.
A table with no header cells at all is reported as 15-002 instead, and a two-row table is not reported. The heuristic does not read the cells, so it will also report tables whose first column is ordinary data; that is the judgement this warning hands you.
The repair is table-headers, and it changes a <TD> into a <TH> only with your approval. It has two ways to get it:
- Proposals. Where the first column is words and the other body cells are mostly numbers — at least four in five — it proposes the first column as row headers, promotes it, and sets
/Scope /Row. On our generated four-row table this cleared both the 15-001 finding and any 15-003. A table of words beside words is not proposed, and stays reported. - A list of cells. Given the structure paths of the cells to promote, it promotes exactly those, whatever the table holds.
The screen-reader preview shows what that changes. On the same table, before the repair it reads the South row’s 2026 cell as 2026, 104; after it, as South, 2026, 104.
Run with neither, it promotes nothing, and when that leaves it nothing to do it says so: no cells were approved for promotion. Separately, adding /Scope to a cell that is already a <TH> is mechanical, and the repair does it whenever it runs — which is what finishes the job if you promoted the cells in Acrobat and left Scope out.
In the app, the repair is the Mark table headers checkbox among the fixes that change what the document means. It runs the proposals; it is ticked when first offered, so leaving it on is a decision too. The app does not let you name the cells yourself; where its proposals are wrong, untick it and set the header cells in Acrobat’s Table Editor instead.
How Taggart handles it
The protocol marks this condition as needing human judgement, so no validator can decide it outright. Taggart applies a heuristic to find the likely cases and reports each one as warning for you to settle in the review queue. A heuristic finds what it was built to find and can miss the rest; what this one looks for is described above.
The fix is Set table headers, Scope and Headers references. It changes what the document means, so Taggart proposes it and waits for your approval rather than applying it unattended.
Whatever Taggart changes, the page still looks identical. Fixes edit the PDF object model, not the content streams, and every remediation is re-rendered and compared against the original at structural similarity ≥ 0.999 before you get the file back. A tool that quietly reflows your document is worse than no tool.
Frequently asked questions
How do I know whether the first column is a header column?
Read across a row and ask what the numbers are about. If the answer is the word in the first cell — North, Q3, Salaries — that cell labels the row and is a header. If the first column is just more data, such as a date in a log where every column matters equally, it is not.
Do I need Scope if the cell is already a TH?
Yes. A TH without Scope is a separate failure, 15-003, because a reader cannot tell whether it heads its row or its column. A row header gets /Scope /Row; the cells of a header row get /Scope /Column.
What about a right-to-left table?
The header column is the one the row starts with in reading order, which in Hebrew or Arabic is the rightmost on the page. In a correctly tagged right-to-left table that is also the first cell of each row in the structure tree, which is the cell Taggart looks at.
Does Taggart fix this automatically?
Not unattended. Its table-headers repair proposes the first column as row headers when it is words beside columns of numbers, and promotes only cells that are proposed or that you name. Promoting a cell to a header is a statement about what the table means.
Where this sits in the standards
| Standard | Reference |
|---|---|
| Matterhorn Protocol 1.1 | Checkpoint 15 (Tables), index 15-001 |
| PDF/UA-1 (ISO 14289-1) | Clause 7.5-1 |
| WCAG 2.1 | 1.3.1 Info and Relationships — Level A |
| EN 301 549 / Section 508 / ADA Title II | All three point at WCAG 2.1 Level AA for non-web documents, so a Level A or AA criterion here is in scope for each of them. |
Guides that cover it
Related conditions
- 15-002 A column has a header cell, but that header cell is not tagged as a headerThe top row labels the columns but is tagged as ordinary data cells.
- 15-003 A TH cell does not contain a Scope attributeHeader cells must declare whether they head a row, a column, or both, unless the table instead uses explicit /Headers ID references on every data cell.
- 15-005 A given cell's header cannot be unambiguously determinedIn a complex table — merged cells, stacked header rows, split spans — Scope alone cannot express the associations, so explicit /Headers references are required.
- 15-004 Content is tagged as a table for information not organized in rows and columnsA table used purely to position content on the page — a two-column layout, a form arrangement — has been tagged as a real table.
Other conditions in checkpoint 15
Checkpoint 15 covers tables. These are its other failure conditions; the ones without a link are in the rule set but do not have a written page yet.
- 15-002 A column has a header cell, but that header cell is not tagged as a headerThe top row labels the columns but is tagged as ordinary data cells.
- 15-003 A TH cell does not contain a Scope attributeHeader cells must declare whether they head a row, a column, or both, unless the table instead uses explicit /Headers ID references on every data cell.
- 15-004 Content is tagged as a table for information not organized in rows and columnsA table used purely to position content on the page — a two-column layout, a form arrangement — has been tagged as a real table.
- 15-005 A given cell's header cannot be unambiguously determinedIn a complex table — merged cells, stacked header rows, split spans — Scope alone cannot express the associations, so explicit /Headers references are required.
Check your own file. Taggart’s validator is free and unlimited — 75 of the 87 Matterhorn conditions software can decide, with the other 12 listed for you to confirm; no watermark, no expiry, and no account needed up to 60 pages.
Checked with Taggart on a generated file that fails this condition on . The Acrobat steps follow Adobe’s documentation and were not walked through by hand. Last updated .