The short version: the failures cluster by production tool, not by author carelessness. And one of those tools takes a fully conforming file and destroys it in a single pass — while making the file 20% smaller, which is exactly why someone runs it.
What we measured, and what we didn't
Two layers of data sit behind this article.
The wide layer is a crawl of 1,682 Hungarian municipal websites, covering 8,469 PDFs. That crawl did not run a full validation — it checked four cheap signals per file: whether the page content is a scanned image, whether a structure tree exists, whether the document has a title, and whether a language is declared. By those four signals alone, 5,433 files (64%) had at least one problem.
Of the 1,682 sites, 1,215 published at least one PDF. Of those 1,215, exactly 39 had no failing file.
Funnel from the 2026 crawl. 1,682 Hungarian municipal websites were crawled. 1,215 of them published at least one PDF. Only 39 of those 1,215 had no failing file on the four cheap signals checked.
Those four signals are not PDF/UA conformance. They are the cheapest possible proxy, and I want to be explicit about that, because the gap between "passes the four signals" and "actually conforms" turns out to be one of the findings.
The narrow layer is this: five real documents from that crawl, plus one of our
own, run through veraPDF 1.30.2 (build 2026-06-03) against the PDF/UA-1
profile. veraPDF is the open-source PDF/UA validator built by the veraPDF Consortium and
funded by the EU's PREFORMA project — its own --version output says exactly
that. When it reports a failure against clause 7.1-3, that is the standard
speaking, not a vendor.
~/.local/share/verapdf/verapdf -f ua1 --format json document.pdf
The five municipal files are identified below as Doc A through Doc E. They are public documents on public websites, but naming the municipalities would put the emphasis in the wrong place: with 39 clean sites out of 1,215, this is not a story about which village got it wrong.
The results
| Document | Pages | Producer | Rules violated | Failed checks | |
|---|---|---|---|---|---|
| Doc A | annual work plan | 4 | Microsoft Word 2013 | 3 | 4 |
| Doc E | service programme | 16 | Lexmark CX622ade | 4 | 19 |
| Doc B | development summary | 4 | Konica Minolta bizhub 223 | 6 | 9 |
| Doc D | grant announcement | 1 | Adobe PSL for Canon | 7 | 245 |
| Doc C | planning study | 53 | GPL Ghostscript 10.06.0 | 13 | 5,997 |
| Ours | sample output | 5 | a11y-pdf v0.1.0 | 0 | 0 |
Read the Producer column, not the failure count. Every one of these documents was written by a person doing their job, and every failure below is a property of the software that wrote the file out.
Doc A: the one that almost made it
Doc A is a Word 2013 export, and Word did its part properly. The file has a
structure tree, MarkInfo/Marked is true, and /Lang is set to hu-HU. The
person who exported it had every reason to believe the job was done.
It fails on four checks:
- 7.21.4.1-1 (×2) — two fonts are not embedded:
TimesNewRomanPSMTandTimesNewRomanPS-BoldMT - 7.1-8 — no XMP metadata stream in the catalog
- 7.1-10 —
ViewerPreferenceshas noDisplayDocTitle
None of these are visible when you open the file. Two of them are one-time
settings in the export dialog. The third — DisplayDocTitle — is why a screen
reader announces 2021.-evi-munkaterv.pdf instead of the document's actual
title, and Word has no checkbox for it at all.
This is the file I'd point at when someone says accessibility is a matter of effort. Someone made the effort here. The toolchain still lost.
Doc E: passing the wrong test
Doc E is where our own cheap crawl signals get embarrassing.
The crawl recorded it as scanned, tagged, and having a title — better on paper than Doc A. Open it up and the picture changes:
Producer : Lexmark CX622ade
Creator : HardCopy
/Title : "Scanned Document"
StructTree: True
A photocopier scanned a paper document, generated a structure tree over the
image, and wrote the literal string Scanned Document into the title field. Our
signal check saw has_title = true. A screen reader user gets told they have
opened a thing called "Scanned Document".
If you are building any kind of automated accessibility scoring, this is the failure mode to design against: presence is not the same as usefulness. Two of our four signals — has-title and is-tagged — were satisfied here by a photocopier that understood nothing about the document it was scanning.
Doc C: the interesting one
Doc C has 5,997 failed checks across 53 pages — 3,223 pieces of untagged content and 2,290 text runs with no determinable language. It has no structure tree at all.
The metadata is what makes it worth a section:
Creator : Microsoft® Word for Microsoft 365
Producer : GPL Ghostscript 10.06.0
Creator is written by the application the document was authored in. Producer
is written by whatever last wrote the file out. So: Word authored this document,
and something then ran it through Ghostscript, which produced the file that is
actually on the website.
We know Word's export does carry structure, because Doc A in the table above is a Word export and it has a structure tree, a marked-content flag and a language. Same authoring tool, opposite outcome — the difference is what happened after the export.
That is a hypothesis, not a finding. So we tested it.
The experiment
Take a file we know is conforming: our own sample output, which veraPDF reports
as compliant: true with zero violations. Run one Ghostscript command:
gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress \
-o after.pdf before.pdf
Then validate again.
StructTreeRoot |
Marked |
/Lang |
DisplayDocTitle |
veraPDF | Size | |
|---|---|---|---|---|---|---|
| before.pdf | yes | true | en |
true | compliant, 0 failures | 55,936 B |
| after.pdf | gone | false | gone | false | 9 rules, 110 failures | 44,967 B |
One pass. The structure tree, the marked-content flag, the document language and the title-display preference are all gone.
We used /prepress, which is the quality-preserving preset — so it is fair to
ask whether a real compression setting behaves differently. It doesn't. All four
standard presets produce the identical validation result:
| Preset | veraPDF | Size |
|---|---|---|
/screen |
9 rules, 110 failures | 34,778 B (−38%) |
/ebook |
9 rules, 110 failures | 44,971 B (−20%) |
/printer |
9 rules, 110 failures | 50,336 B (−10%) |
/prepress |
9 rules, 110 failures | 44,967 B (−20%) |
The preset governs image quality. It has no bearing on whether the structure
survives, because the structure isn't image data — it is the part of the file
that pdfwrite doesn't rebuild at all.
And the pages themselves? Rendered at 144 DPI and compared in greyscale,
/prepress and /ebook produce zero differing pixels out of 2,005,644 per
page across all five pages — the largest single-channel deviation is 4 of 255,
which no eye will find. Only /screen changes anything visible, and only on one
page out of five, where a photograph gets downsampled: 1.4% of pixels differ
there.
So the visual cost of this operation depends on the preset you choose. The accessibility cost does not.
Ghostscript 10.07.1 was used for the reproduction; the file in the wild came from 10.06.0.
It is worth being precise about what is and isn't documented here, because this
is the part people will want to check. Ghostscript's official
High Level Devices documentation
never mentions logical structure, tagging, accessibility or PDF/UA at all. What
it does say is that pdfwrite produces a new file where "the actual insides of
the PDF file are not the same as the original", and that "any part of the
original input which does not actually make marks on the page (such as
hyperlinks, bookmarks, comments etc) will normally not be present in the output".
A structure tree makes no marks on the page. It is, in the terms of that sentence, exactly the kind of thing that "will normally not be present in the output" — and the measurement above is what that looks like in a real document.
So this is expected behaviour rather than a bug. But it is expected behaviour described in a sentence about hyperlinks and comments, on a page that never uses the word accessibility — and the command itself gives no warning.
What this changes in practice
Validate after the last step, not after authoring
If your workflow is
Word → PDF → optimise → publish, then validating the export tells you nothing
about the file your users download. Doc C's author almost certainly produced a
tagged PDF and never saw what got published.
Check the Producer field on your own published files
Two fields tell you
almost the whole story: Creator names the program the document was written in,
Producer names whatever last wrote the file out. If Creator says Word and
Producer says Ghostscript, a printer model, or a compression utility, then your
structure tree is probably gone — and you can see both without installing
anything.
How to read those two fields, whatever you have on your machine
Windows, no extra software
Right-click the PDF in File Explorer → Properties → the Details tab. The document's embedded fields are listed there, including the program that produced it.
Any platform, using the free Adobe Acrobat Reader
Open the file →
File → Properties (Ctrl+D, or Cmd+D on a Mac) → the Description tab.
"Application" is the Creator field and "PDF Producer" is the Producer field.
This is the most complete view, and it is the same dialog on Windows, macOS and
Linux.
macOS Preview
Tools → Show Inspector (Cmd+I) opens the document information panel. If the field you are after isn't listed there, the Acrobat Reader dialog above has the full set.
A whole folder at once
If you need to check hundreds of files rather than one, this prints the fields for a single document and can be wrapped in a loop:
python -c "import pikepdf,sys; print(pikepdf.open(sys.argv[1]).docinfo)" file.pdf
Treat file-size optimisation as destructive on tagged PDFs
Compress the images before you build the accessible PDF, not after.
Where the validator stops
Our own sample file passes with zero violations, and I want to be honest about what that green result does and does not mean.
veraPDF checks structure, not sense. It will confirm that every image carries an
alternate description, and it will do so just as happily when that description
reads image1.png — which, in the files that come to us for remediation, it
frequently does.
Reading order is the harder case. A heading tagged H2 satisfies the standard
whether or not it belongs where it sits, so a file can validate cleanly while a
screen reader walks the page in an order no sighted reader would recognise. Table
scope attributes have the same problem, with the added difficulty that they look
like semantics and are usually guesswork.
Every one of those is a judgement call, and every one of them is where automated remediation — ours included — either gets help from a human or gets it wrong. A conforming file is the floor, not the ceiling. Anyone selling you a green tick as the finish line is selling you the floor.
If you want to check your own documents
Run veraPDF against PDF/UA-1 on the files you actually publish, sorted by how
often they are downloaded rather than by how recent they are. Start with the
Producer field — it will tell you in seconds whether the problem is your export
settings or something downstream that you didn't know was there.
If you want to see the failure list for one of your files without installing anything, our PDF accessibility checker reports the same clauses. What the errors mean one by one is written up in the PDF/UA error reference, and the standard itself — what PDF/UA-1 requires and why — is covered in the PDF/UA guide.