We validated real-world PDFs against PDF/UA-1. One tool destroyed compliance in a single pass.

Most writing about PDF accessibility describes what a good file looks like. This one starts from the other end: we took documents that are actually published on public websites, ran the official PDF/UA validator on them, and looked at what the failures have in common.

11 perc olvasás

Ezen az oldalon
  1. What we measured, and what we didn't
  2. The results
  3. Doc A: the one that almost made it
  4. Doc E: passing the wrong test
  5. Doc C: the interesting one
  6. The experiment
  7. What this changes in practice
  8. Where the validator stops
  9. If you want to check your own documents

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.

39 out of 1,215 is 3%. The bar for it is not a rendering error.

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: TimesNewRomanPSMT and TimesNewRomanPS-BoldMT
  • 7.1-8 — no XMP metadata stream in the catalog
  • 7.1-10ViewerPreferences has no DisplayDocTitle

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.

Zoltán Csordás

Alapító, a11yfy

Csordás Zoltán akadálymentesítési fejlesztő, az a11yfy alapítója. Ő építi az a11yfy.com mögötti PDF/UA-pipeline-t, és a hetei nagy része tag-fákkal, veraPDF-jelentésekkel és azzal telik, amit ezekből egy képernyőolvasó felolvas. 2026-ban 1 682 magyar önkormányzati honlap 8 469 PDF-jét mérte végig, hogy megtudja, mekkora valójában a baj. Budapesten él.