PDF Attachments & Hybrid Invoice Check
Files ride inside a PDF without appearing on any page. This lists them — and when the PDF is a Factur-X or ZUGFeRD invoice, it checks whether the container is built the way receivers expect, then puts the invoice itself through the Article 226 engine.
🔒 Your document never leaves your browser.
Drop a PDF here
One PDF at a time · nothing is uploaded
A hybrid invoice is not “a PDF with an XML in it”
Factur-X and ZUGFeRD carry the machine-readable invoice as an attachment inside a PDF/A-3 file. Whether a receiver can actually find it depends on details that are invisible when you open the document:
- The filename is part of the contract. Receivers look the attachment up by
name: factur-x.xml, zugferd-invoice.xml, xrechnung.xml, order-x.xml. A file called
invoice.xmlis not found, however valid its contents. - The relationship has to say what the file is. PDF/A-3 records that in
/AFRelationship:Alternative— the XML and the pages are two renderings of one invoice — orSource, which ZUGFeRD 2.1 requires for the BASIC, EN 16931 and EXTENDED profiles when the recipient is outside Germany and the PDF was produced from the XML. - It must be registered twice. Once as an associated file in
/AF, once as an ordinary attachment in/EmbeddedFiles— the second one exists for the large amount of software that never implemented PDF/A-3 associated files. Present in only one place is the failure where the sender sees a valid invoice and the receiver sees none.
And then: is the invoice itself right?
Pulling the XML out is the easy part — several free tools do it. What happens here afterwards is the part that is ours: the invoice is mapped into the same model the invoice generator and the fields checker use, and run through the same rules — Article 226 particulars, totals computed per VAT rate rather than copied from the file, and the VAT and IBAN format checks. A file whose stated totals disagree with its own lines surfaces there.
Honest limits
The reader takes a bounded set of paths out of the Cross Industry Invoice by element name; it
is not a full EN 16931 semantic mapping, and anything it could not read is
listed as unread rather than guessed. The attachment list is read from the document catalog
itself — both the /EmbeddedFiles name tree and the /AF array — so
the relationship column is filled in here exactly as it is by the
MCP server.
Every check this tool runs (8 rules)
FXA-001 The embedded invoice file is not named as the standard requires
The filename is part of the contract, not a preference: readers look the attachment up by name. ZUGFeRD 2.1 and Factur-X use factur-x.xml, ZUGFeRD 2.0 used zugferd-invoice.xml. A file called invoice.xml is invisible to a receiver that goes looking for the prescribed name, however valid its contents.
Fix: Rename the embedded file to factur-x.xml unless you are deliberately producing an older ZUGFeRD version.
FXA-002 The associated-file relationship is missing or not one the standard allows
PDF/A-3 records why a file is attached in /AFRelationship. A hybrid invoice uses Alternative — the XML and the pages are two renderings of the same invoice — or Source, which ZUGFeRD 2.1 requires for the BASIC, EN 16931 and EXTENDED profiles when the recipient is outside Germany and the PDF was produced from the XML. Anything else (Data, Supplement, Unspecified) tells the receiver this is not the invoice.
Fix: Set /AFRelationship to Alternative, or to Source in the case the standard names.
FXA-003 The XML is an associated file but not a regular attachment
The invoice XML has to appear in both places: in the document catalog /AF array as an associated file, and in the /EmbeddedFiles name tree as an ordinary attachment. The second one exists for software that does not implement PDF/A-3 associated files at all — and there is a lot of it. Present in only one place is the failure where the sender sees a valid file and the receiver sees none.
Fix: Register the attachment in /EmbeddedFiles as well as /AF.
FXA-004 The XMP metadata does not declare the hybrid-invoice extension schema
The container is supposed to announce itself in XMP: document type, the filename of the embedded XML, the version, and the profile. Receivers use it to decide whether to look for an invoice at all before opening any attachment.
Fix: Add the Factur-X / ZUGFeRD extension schema block to the XMP packet.
FXA-005 The file does not declare PDF/A-3 conformance
A hybrid invoice is a PDF/A-3 file — that is the part of the PDF/A family that permits arbitrary attachments. Without the declaration the document is an ordinary PDF that happens to carry a file, which archiving systems treat differently.
FXA-006 The embedded file is not a readable invoice XML
The attachment is present under the right name but does not parse as XML, or parses but is not a Cross Industry Invoice. A receiver that trusts the filename gets a parse error instead of an invoice.
FXA-007 The profile in the metadata does not match the profile inside the XML
The profile is stated twice — once in the XMP block and once inside the XML as the guideline parameter. When they disagree, a receiver that reads one is applying a different rule set from a receiver that reads the other.
FXA-008 The PDF carries attachments beyond the invoice
Any file can ride along inside a PDF, and attachments travel with the document without appearing on any page. They are listed here for the same reason the metadata checker lists what is in a file: what leaves the building should be something you chose to send.
yaktool engineering note, not a requirement of the Factur-X specification: listing non-invoice attachments is a privacy-hygiene check of our own, in the same spirit as the PDF redaction and EXIF tools.