An archival format as the carrier
PDF/A is the family of PDF flavours built for long-term retention. The governing idea: a file should look the same in twenty years as it does today — even if the typeface, the colour profile or the program that produced it are long gone.
The typical requirements follow from that. Fonts must be embedded. Colour profiles must be shipped along. References to external content are forbidden. Everything the file needs in order to render must live inside it.
Why it has to be A-3
Within the family the levels differ in what may be embedded:
| Flavour | Embedding arbitrary files | Suitable for ZUGFeRD |
|---|---|---|
| PDF/A-1 | 🔴 no | no |
| PDF/A-2 | 🟡 PDF/A only | no |
| PDF/A-3 | 🟢 yes | yes |
PDF/A-1 forbids attachments outright — they would be a reference to something whose rendering cannot be guaranteed. PDF/A-2 relaxed that, but only for other PDF/A files.
PDF/A-3 is the first to permit embedding an arbitrary file and marking it as belonging. That is exactly what a hybrid format needs: the XML is not a PDF, and it should still be part of the archival object.
💡 The ordering matters for understanding this: PDF/A-3 was not invented for e-invoices. ZUGFeRD used an existing capability — and is today its best-known application.
What the embedding looks like
The embedded XML is not a loose attachment; it carries a relationship marker describing its role:
1invoice.pdf (PDF/A-3b)2└── attachment3 ├── filename (fixed by the specification)4 ├── relationship Alternative5 └── MIME type text/xmlAlternative says: this file is another representation of the same content —
not an enclosure, not a supplementary document. Which is precisely what the XML
invoice is.
🔴 The filename is no side issue here. It is fixed by the specification, and a checking program looks for exactly that name. If a different one is there, the check reports "no XML found" — even though the file is present. That message points in the wrong direction and regularly costs hours.
Where validation fails
For a ZUGFeRD file a validator checks two things independently: the shell (is this valid PDF/A-3?) and the content (does the XML satisfy the rules of its profile?). The two can fail separately.
The most common reasons on the shell side have nothing to do with invoices:
- Fonts not embedded. The classic. A PDF referencing a system typeface is not archival.
- Transparency. Forbidden in PDF/A-1, permitted in A-2 and A-3 — libraries still working internally to A-1 stumble here.
- Missing colour profile. Without a profile it is undefined what a colour should look like.
- Encryption. A password-protected PDF cannot be archive-conformant.
These faults arise in PDF generation, not in invoice logic. Looking for them in the invoice data model is looking in the wrong place.
Conformance levels a and b
You will meet notations like PDF/A-3b or PDF/A-3a:
- b (basic) — reliable visual reproduction is guaranteed.
- a (accessible) — the logical document structure is additionally recorded in machine-readable form, for accessibility.
For ZUGFeRD, b is normally sufficient. Level a is considerably more work to
produce and is not required by the invoice rules.
And retention
Because PDF/A-3 is an archival format, it is tempting to think the retention question is thereby answered. Not entirely.
The format secures legibility over time. It does not secure unalterability or the traceability of every edit — that is the job of the system the file lives in.
🔵 And: what you retain is the whole file, not the extracted XML and not a printout. The original is the combination of visible document and embedded data.