Validation & rules

Validating an e-invoice: the three stages and what each one checks

An e-invoice is checked in three stages: syntax (is the XML well-formed?), schema (are the fields correctly typed and ordered?) and business rules (does the content make sense?). Almost every rejection happens at stage three — the XML is flawless, but a mandatory detail is missing or two amounts disagree.

Also:
E-Rechnung validieren · XRechnung prüfen · invoice validation
Reviewed on 2026-08-26.

Why three stages, not one

"Is this invoice valid?" is not one question. It is three, answered in order, and each finds a different class of error. Knowing which stage failed turns a message you have to decode into one you can act on.

Stage 1 — syntax

Is the document well-formed XML at all? Unclosed tags, broken encoding, a truncated upload. This stage knows nothing about invoices; it would treat any XML the same way.

Failures here are rare and almost always a transport problem, not a data problem.

Stage 2 — schema

Does the document match its XSD? Does cbc:IssueDate really carry a date, does cac:AccountingSupplierParty sit where it is allowed to sit, is the cardinality respected? This stage also decides whether the document is in the right syntax — CII and UBL are two different XSDs for the same business content.

Failures here almost always mean the generator puts a field in the wrong place or with the wrong type.

Stage 3 — business rules

Most documents that fail, fail here, and the message is hardest to read here. Business rules are written in Schematron and test factual claims with XPath expressions:

xml
1<assert test="cac:Party/cac:Contact" flag="fatal" id="DE-R-002">
2 The group "SELLER CONTACT" (BG-6) shall be provided.

At this point the document is impeccable XML and schema-conformant. One mandatory business detail is missing — and that alone is enough to reject it.

Three rule sets apply at once

A German B2G invoice is not checked against one rule set but against several stacked on top of each other:

LayerExample ruleOrigin
European standardBR-11 — the buyer address needs a country codeEN 16931
Arithmetic rules of the standardBR-CO-10 — line totals = net amountEN 16931
National specialisationDE-R-001 — payment instructions (BG-16) are mandatoryXRechnung / CIUS

A document must pass all of them. That is why validating against the European standard alone is not sufficient when the recipient is a German public authority.

How to actually locate a failure

A usable message names three things: the rule ID, the affected field in BT/BG notation, and the severity. The rule ID lets you look up the XPath expression that failed — and that expression tells you exactly where in the document the check looked.

The most common time sink is not mapping the BT number onto your own data model. BT-10 is the routing ID in a German public-sector context; searching your ERP for "routing" finds it, searching for "BT-10" does not.

Validation is not a one-off

Rule sets get new versions, and severities move with them. An invoice that passed with a warning last year can fail hard at the same spot this year. If you generate e-invoices, validate against the version your recipient runs — not the one that was current when you built the integration.

Frequently asked questions

Try it right here

Upload a real e-invoice and see which rules fire. No account needed, and the file does not leave the validation run.

Processed in EU data centers · no persistent storage · GDPR-compliant.

Need this automated?

Generate, validate and parse e-invoices via API — 20 API calls/month free, no credit card.