Nordlet

← Blog

EN 16931 Compliance: Peppol, Factur-X and ZUGFeRD Checked Against the Official Rules

We ran the invoice files Nordlet produces through the official EN 16931 validation rules. The Peppol and Romanian files pass. The Factur-X files break two rules, and this article names them.

Nordlet Team · · 3 min read

EN 16931 is the European standard for the content of an electronic invoice. It defines the business terms an invoice carries (seller, buyer, lines, VAT breakdown, totals) and the business rules those terms must satisfy, for example that the VAT breakdown adds up to the invoice total. The standard can be written in two XML formats: UBL 2.1 and UN/CEFACT Cross Industry Invoice (CII).

Most European e-invoicing formats are built on EN 16931:

  • Peppol BIS Billing 3.0 is EN 16931 in UBL with extra Peppol rules.
  • Romanian e-Factura (CIUS-RO) is EN 16931 in UBL with extra Romanian rules.
  • Factur-X (France) and ZUGFeRD 2.3 (Germany) carry EN 16931 in CII. In the "EN 16931" profile, which Nordlet writes, the two formats use the same XML.

If an invoice breaks an EN 16931 rule, it also breaks every format built on top of it.

How we checked

The European Commission refers to the validation rules published by the CEN technical committee for e-invoicing (CEN/TC 434) on GitHub. We used the newest release, 1.3.17 of 12 October 2026, for both UBL and CII. The rules are written in Schematron and compiled to XSLT, and we ran them with the Saxon-HE 12.5 XSLT engine.

The invoice files were produced by Nordlet's current code from sample data. The seller is a Lithuanian company; the buyers are a Lithuanian company, a German company and, in the Peppol export case, a US company. The sample invoices have a 21% VAT line and a 0% line with an exemption note.

Results

What Nordlet writes Files checked Result
Peppol BIS Billing 3.0 (UBL) 7: domestic invoice, credit note, intra-EU sale, export, reverse charge, seller not registered for VAT, invoice in USD with a discount All pass: 0 errors, 0 warnings
Romanian e-Factura (UBL, CIUS-RO) 4: domestic invoice, credit note, intra-EU sale, invoice in USD with a discount All pass
Factur-X / ZUGFeRD (CII, profile EN 16931) 4: domestic invoice, credit note, intra-EU sale, invoice in USD with a discount All 4 fail, 1 error each

The two rules the Factur-X files break

BR-Z-10: a zero-rated line must not carry an exemption reason

EN 16931 has separate VAT categories for a 0% rate ("Z", zero rated) and for an exempt supply ("E", exempt). Only an exempt supply states a reason. Rule BR-Z-10 says that a VAT breakdown in category "Z" must not have an exemption reason code (BT-121) or exemption reason text (BT-120).

The Factur-X builder writes the reason text "Taux zéro" on every zero-rated breakdown, so three of the four files fail. It also ignores the exemption note entered on the line. The Peppol builder handles the same line correctly: when a 0% line has an exemption note, it writes the line as exempt ("E") and uses the note as the reason.

BR-IC-12: an intra-EU sale must state the country of delivery

Rule BR-IC-12 says that when the VAT breakdown has the category "K" (intra-Community supply), the deliver-to country code (BT-80) must not be empty. The country of delivery shows that the goods left the seller's country.

The Factur-X builder does not write a deliver-to country, so the intra-EU file fails. The Peppol builder writes the buyer's country as the delivery country for these sales.

What this check does not cover

  • XML schema. We ran the business rules only, not the UBL and CII schema (XSD) checks.
  • Fields Nordlet does not write. Rules on terms that the files do not contain did not run. Examples are document-level charges, prepaid amounts, the invoicing period and purchase order references.
  • National rules on top of EN 16931. We did not check the French e-invoicing reform rules or the German XRechnung rules. The Peppol-specific rules are checked by a separate Nordlet script, which uses the OpenPeppol rule sets.
  • The PDF part of Factur-X. A Factur-X invoice is a PDF/A-3 file with the XML attached to it. The check covers the XML only.