ZUGFeRD vs XRechnung: A Technical Comparison for ERP Developers
ZUGFeRD and XRechnung are Germany's two e-invoice formats — but they solve different problems. This guide covers the XML structures, validation rules, profile mappings, and integration patterns ERP developers need to choose the right format.
ZUGFeRD vs XRechnung: A Technical Comparison for ERP Developers
If you're building e-invoicing into an ERP system for the German market, you'll hit this question fast: should you generate ZUGFeRD invoices, XRechnung invoices, or both?
The short answer: they're not competing formats. They serve different use cases, use different XML syntaxes, and follow different validation rules — but they both implement the same European standard (EN 16931). Understanding the technical differences is what separates a clean integration from months of debugging validation errors.
This guide breaks down exactly what's different at the XML level, which validation rules apply to each, and how to decide what your ERP integration needs to support.
The 30-Second Overview
| ZUGFeRD | XRechnung | |
|---|---|---|
| Full name | Zentraler User Guide des Forums elektronische Rechnung Deutschland | Standard XRechnung |
| XML syntax | UN/CEFACT Cross Industry Invoice (CII) | UBL 2.1 (primary) or CII |
| Delivery format | Hybrid: PDF/A-3 with embedded XML | Pure XML |
| Visual representation | Yes — the PDF is human-readable | No — requires a viewer/renderer |
| Use case | B2B invoicing (any recipient) | B2G invoicing (German public sector), increasingly B2B |
| Maintained by | FeRD (Forum elektronische Rechnung Deutschland) | KoSIT (Koordinierungsstelle für IT-Standards) |
| Current version | ZUGFeRD 2.3 / Factur-X 1.0.07 | XRechnung 3.0.2 |
| EN 16931 compliance | Yes (Comfort profile and above) | Yes (by definition — it IS the German CIUS) |
What EN 16931 Actually Means for Both Formats
EN 16931 is the European standard that defines the semantic data model for electronic invoices. It specifies what information an e-invoice must contain (business terms like BT-1 Invoice number, BT-24 Specification identifier, etc.) — but it doesn't specify how to encode that information in XML.
That's where the syntaxes come in:
- UBL 2.1 (Universal Business Language) — maintained by OASIS. This is what XRechnung primarily uses.
- CII D16B (Cross Industry Invoice) — maintained by UN/CEFACT. This is what ZUGFeRD uses.
Both syntaxes can express the same EN 16931 business terms. But the XML element names, namespaces, and document structure are completely different.
The Same Invoice, Two XML Syntaxes
Here's how the same invoice number (BT-1) looks in each syntax:
CII (ZUGFeRD):
<rsm:CrossIndustryInvoice
xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100">
<rsm:ExchangedDocument>
<ram:ID>INV-2026-0042</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20260323</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<!-- ... -->
</rsm:CrossIndustryInvoice>
UBL (XRechnung):
<ubl:Invoice
xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
<cbc:ID>INV-2026-0042</cbc:ID>
<cbc:IssueDate>2026-03-23</cbc:IssueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<!-- ... -->
</ubl:Invoice>
Same data. Completely different XML. This is why you can't just "convert" between formats by renaming elements — the document structure, date formatting, and nesting hierarchy all differ.
ZUGFeRD Deep Dive: The Hybrid Format
ZUGFeRD is a hybrid e-invoice format. Each ZUGFeRD invoice is a PDF/A-3 file with a CII XML file embedded as an attachment. The PDF contains the human-readable invoice. The XML contains the machine-readable structured data.
This dual-format approach solves a real problem: not every invoice recipient has software that can parse XML. With ZUGFeRD, the recipient can open the PDF in any viewer and read the invoice visually, while their ERP system extracts the XML for automated processing.
ZUGFeRD Profiles
ZUGFeRD defines multiple profiles that control how much data the embedded XML contains:
| Profile | EN 16931 Compliant | XML Content | Use Case |
|---|---|---|---|
| Minimum | No | Invoice reference only (type, number, date, amounts) | Archival, basic automation |
| Basic WL | No | Header + line-level data without line details | Simple B2B |
| Basic | No | Full line items but limited metadata | Standard B2B |
| EN 16931 (Comfort) | Yes | All EN 16931 mandatory + conditional fields | EU-compliant B2B |
| Extended | Yes (superset) | EN 16931 + additional fields (delivery terms, payment details) | Complex supply chains |
| XRechnung | Yes | EN 16931 + German CIUS rules | German public sector via ZUGFeRD |
The critical distinction: only Comfort (EN 16931) and above are EN 16931 compliant. If you're building an integration that needs to meet the EU e-invoicing standard, Minimum and Basic profiles are not sufficient.
The XRechnung Profile Within ZUGFeRD
Here's where it gets confusing: ZUGFeRD 2.3 includes an "XRechnung" profile. This embeds a CII XML file that follows XRechnung's German CIUS (Country-Specific Usage Specification) rules inside the ZUGFeRD PDF/A-3 container.
This means you can send a ZUGFeRD invoice to a German public sector buyer and have it accepted — because the embedded XML meets XRechnung's requirements. The specification identifier in the XML makes this explicit:
<!-- ZUGFeRD with XRechnung profile -->
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
Compare to a standard ZUGFeRD EN 16931 profile:
<!-- ZUGFeRD EN 16931 (Comfort) profile -->
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
The urn:xeinkauf.de:kosit:xrechnung_3.0 identifier tells the validator to apply XRechnung-specific business rules (the BR-DE rules) on top of the EN 16931 core rules.
XRechnung Deep Dive: The Pure XML Standard
XRechnung is Germany's national implementation of EN 16931 — technically called a CIUS (Core Invoice Usage Specification). It adds country-specific rules on top of the European standard.
Unlike ZUGFeRD, XRechnung invoices are pure XML. No PDF wrapper. No visual representation. Just structured data. This makes them ideal for fully automated processing but requires the recipient to have software that can render or process the XML.
XRechnung Supports Two Syntaxes
A common misconception: XRechnung is not UBL-only. It officially supports both:
- UBL 2.1 — the primary and most widely used syntax
- CII D16B — the same syntax ZUGFeRD uses
Both are valid XRechnung documents when they include the correct specification identifier and pass XRechnung validation. In practice, ~90% of XRechnung implementations use UBL because that's what the German public sector portal (ZRE/OZG-RE) primarily processes.
XRechnung-Specific Business Rules (BR-DE)
This is where XRechnung differs most from vanilla EN 16931. KoSIT defines additional business rules prefixed with BR-DE that enforce German requirements:
| Rule | What It Checks | Common Error |
|---|---|---|
| BR-DE-1 | Payment instructions must be present | Missing PaymentMeans entirely |
| BR-DE-2 | At least one contact phone or email on buyer | Missing buyer contact details |
| BR-DE-3 | Seller contact must include phone | Having email but no phone |
| BR-DE-4 | Seller contact must include email | Having phone but no email |
| BR-DE-5 | Seller contact must include name | Anonymous contact block |
| BR-DE-13 | Delivery date or invoice period must be stated | Missing both ActualDeliveryDate and InvoicePeriod |
| BR-DE-16 | Buyer reference (Leitweg-ID) is mandatory | Missing BuyerReference element |
| BR-DE-17 | Payment method code must be 10, 30, 48, 49, 57, 58, or 59 | Using unsupported payment method codes |
| BR-DE-18 | Payment account (IBAN) is mandatory for bank transfers | Missing IBAN for credit transfer payments |
These rules are checked by Schematron validation — a rule-based validation layer that runs after XSD schema validation passes. An invoice can be valid CII or UBL XML but still fail XRechnung validation because of missing BR-DE fields.
For a full guide on how Schematron validation works in e-invoicing, see our Schematron rules explainer.
Validation: Where the Formats Really Diverge
Both ZUGFeRD and XRechnung invoices go through multi-layer validation:
Layer 1: XML Schema (XSD) Validation
Checks that the XML document structure is well-formed and uses the correct elements/types.
- ZUGFeRD (CII): Validates against the UN/CEFACT CII D16B schema
- XRechnung (UBL): Validates against the OASIS UBL 2.1 schema
- XRechnung (CII): Same CII schema as ZUGFeRD
Layer 2: EN 16931 Core Rules (Schematron)
Business rules that apply to all EN 16931 invoices regardless of format:
- BR-1 through BR-65: Core business rules (e.g., BR-1: "An Invoice shall have a Specification identifier")
- BR-CO-1 through BR-CO-26: Calculation rules (e.g., BR-CO-10: "Sum of Invoice line net amount = Σ Invoice line net amount")
- BR-CL-1 through BR-CL-26: Code list rules (e.g., BR-CL-1: "Currency code must be from ISO 4217")
Layer 3: CIUS / Profile Rules (Schematron)
Format-specific rules:
- XRechnung: BR-DE rules (see table above) — strictly enforced
- ZUGFeRD (EN 16931 profile): No additional rules beyond EN 16931 core
- ZUGFeRD (XRechnung profile): BR-DE rules apply (same as pure XRechnung)
- ZUGFeRD (Basic/Minimum): Profile-specific subset rules — fewer required fields
What This Means for Your Integration
If you're building a validator or generating invoices:
- XRechnung always validates against 3 layers — XSD + EN 16931 core + BR-DE rules
- ZUGFeRD EN 16931 profile validates against 2 layers — XSD + EN 16931 core rules
- ZUGFeRD sub-profiles (Basic, Minimum) validate against fewer rules — easier to generate, but not EU-compliant
You can test both formats against all validation layers using Invoice Navigator's free validator. Upload a ZUGFeRD PDF or XRechnung XML file and get instant feedback with rule-level error details.
Decision Matrix: Which Format Does Your ERP Need?
Generate XRechnung (UBL) When:
- Sending to German public sector — it's mandatory since November 2020
- Your recipients require pure XML — no PDF needed
- You're connecting via Peppol — XRechnung UBL is the standard for German Peppol participants
- Your system already supports UBL — many international ERP systems have UBL modules
Generate ZUGFeRD When:
- Your recipients include non-technical businesses — the PDF ensures they can always read the invoice
- You need backward compatibility — recipients without e-invoice processing can use the PDF
- You're operating across DACH + France — ZUGFeRD 2.3 is identical to Factur-X 1.0.07 (the French standard)
- Your integration pipeline uses CII — ZUGFeRD natively uses CII syntax
Generate Both When:
- You serve both public sector and private sector — XRechnung for B2G, ZUGFeRD for B2B
- You're building a multi-tenant ERP — different customers have different format requirements
- You want maximum compatibility — ZUGFeRD with XRechnung profile covers both cases in one file
Implementation Patterns
Pattern 1: Single EN 16931 Data Model → Multiple Outputs
The cleanest architecture: maintain a single internal invoice data model that maps to EN 16931 business terms, then serialize to the target format at output time.
Internal Invoice Object
↓
EN 16931 Business Terms (BT-1, BT-2, ...)
↓
┌─────────────────────────────┐
│ Output Serializer │
├─────────────────────────────┤
│ → UBL XML (XRechnung) │
│ → CII XML (ZUGFeRD XML) │
│ → PDF/A-3 + CII (ZUGFeRD) │
└─────────────────────────────┘
↓
Validation API (Invoice Navigator)
↓
Delivery (Peppol, email, portal upload)
This pattern avoids maintaining separate data mappings for each format. The EN 16931 business terms are your canonical intermediate representation.
Pattern 2: Validate Before Delivery
Regardless of which format you generate, always validate before sending. E-invoice validation catches issues that your generation code might miss — especially Schematron business rules that depend on field combinations (e.g., BR-DE-17 checks that PaymentMeansCode is in the allowed set only when certain payment conditions exist).
# Validate an XRechnung UBL file via Invoice Navigator API
curl -X POST https://api.invoicenavigator.eu/v1/validate \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/xml" \
-d @invoice-xrechnung.xml
# Validate a ZUGFeRD PDF
curl -X POST https://api.invoicenavigator.eu/v1/validate \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/pdf" \
-d @invoice-zugferd.pdf
The API returns structured error responses with the exact rule ID, severity, location in the XML, and a human-readable explanation. See the API docs for the full response schema.
Common Pitfalls
1. Assuming ZUGFeRD Basic = EN 16931 compliant. It's not. Only the EN 16931 (Comfort), Extended, and XRechnung profiles meet the EU standard. If a customer says "we accept EN 16931 invoices," don't send them ZUGFeRD Basic.
2. Using CII syntax for XRechnung without testing. While XRechnung officially supports CII, the validation rules were originally written for UBL. CII implementations sometimes hit edge cases in Schematron rules that expect UBL-specific XPath expressions. Always validate CII-based XRechnung files before going live.
3. Hardcoding the specification identifier.
The CustomizationID (UBL) or GuidelineSpecifiedDocumentContextParameter (CII) must exactly match the XRechnung version your XML conforms to. When XRechnung releases a new version (e.g., 3.0 → 3.0.2), the identifier changes. Validators check this first.
4. Forgetting the Leitweg-ID for public sector invoices.
BR-DE-16 makes BuyerReference mandatory in XRechnung. For public sector recipients, this must be their Leitweg-ID (a structured routing identifier). Missing or malformed Leitweg-IDs are the #1 rejection reason on the ZRE portal.
5. Ignoring the PDF/A-3 requirement in ZUGFeRD.
The PDF container must be PDF/A-3 compliant — not regular PDF, not PDF/A-1, not PDF/A-2. Many PDF libraries default to non-archival PDF. Use a library that explicitly supports PDF/A-3 output (like Apache PDFBox with the PDF/A module, or iText with PdfAConformance.PDF_A_3B).
Frequently Asked Questions
Is ZUGFeRD the same as Factur-X?
Technically yes. ZUGFeRD 2.x and Factur-X 1.x are joint specifications maintained by FeRD (Germany) and FNFE-MPE (France). The XML schemas are identical. The only difference is branding — German-speaking markets use "ZUGFeRD," French-speaking markets use "Factur-X."
Can I send ZUGFeRD to German public sector?
Yes, if you use the XRechnung profile within ZUGFeRD. The embedded CII XML must include the XRechnung specification identifier and pass all BR-DE validation rules. The ZRE portal accepts ZUGFeRD files with the XRechnung profile.
Which format will Germany require for B2B from 2027?
Germany's B2B e-invoicing mandate (effective January 2027 for sending, with transition periods) requires invoices in EN 16931-compliant format. Both XRechnung and ZUGFeRD (EN 16931 profile or higher) qualify. The mandate is format-neutral as long as EN 16931 compliance is met.
Do I need separate validators for each format?
No. A proper e-invoice validator handles both syntaxes and all profile levels. Invoice Navigator's validator automatically detects the format (ZUGFeRD PDF, CII XML, or UBL XML), identifies the profile/CIUS, and applies the correct validation rules. Try it free →
What about Peppol — does it use ZUGFeRD or XRechnung?
Peppol BIS Billing 3.0 uses UBL 2.1 syntax. In the German Peppol network, invoices are sent as XRechnung UBL documents. ZUGFeRD (CII-based) is not natively supported on Peppol, though some access points offer CII-to-UBL conversion. If you're integrating with Peppol, implement UBL output.
How do I detect which format an incoming invoice uses?
Check the root XML element:
<ubl:Invoice>or<ubl:CreditNote>→ UBL (likely XRechnung)<rsm:CrossIndustryInvoice>→ CII (likely ZUGFeRD)
For ZUGFeRD PDFs, check for an embedded XML attachment named factur-x.xml or zugferd-invoice.xml in the PDF/A-3 container.
Then check the CustomizationID (UBL) or GuidelineSpecifiedDocumentContextParameter/ID (CII) to identify the exact profile and CIUS version.
Need to validate invoices in both formats? Invoice Navigator's validator handles ZUGFeRD (all profiles), XRechnung (UBL and CII), Peppol BIS, and 20+ country-specific formats. Try the free validator or check the API docs for programmatic validation.
Check Your Compliance Status
Find out exactly what your business needs to do for e-invoicing compliance.
Use Obligation Finder