Guide
How to read KoSIT validator errors
The validator rejected your invoice — and the message reads like a standard, not a fix. Here is how the report is structured, and how to resolve the most common findings.
Updated on
What is the KoSIT validator?
KoSIT (Germany's coordination office for IT standards) maintains the official reference implementation that checks every XRechnung against the business rules of EN 16931 and the German XRechnung specification. normbill runs exactly this validator — pinned to version 1.6.2 with the XRechnung 3.0.2 scenario — on every generate and validate. It has the final word on conformance.
How is a KoSIT finding structured?
Each finding (a Schematron assertion) has four parts:
- Rule id — e.g.
BR-DE-15; the prefix names the rule family (table below). - Severity —
errormakes the document non-conformant,warningdoes not. - Official rule text — phrased in standards language.
- XPath — the location in the XML, not in your source data. That is the gap the normbill 422 report closes: it names the path in your request JSON instead.
| Prefix | Family | Typical cause |
|---|---|---|
BR-DE-* | German XRechnung rules (CIUS) | Mandatory fields missing: contact, payment, Leitweg-ID |
BR-CO-* | Calculations & conditions | Totals do not add up, dependent fields missing |
BR-DEC-* | Decimal precision | More than two decimal places in amounts |
BR-CL-* | Code lists | Disallowed code, e.g. type_code 381 in UBL |
BR-S-*, BR-AE-*, … | VAT categories | Tax category inconsistent with rates or exemptions |
UBL-SR-*, UBL-CR-* | UBL binding | Structure of the UBL XML |
XSD | XML schema | The XML does not match the schema |
Every family, with every individual rule explained in English and German, lives in the rule reference.
The eight most common errors — cause and fix
| Rule | What the validator objects to | Fix in the normbill JSON |
|---|---|---|
BR-DE-15 | The buyer reference (BT-10) is missing — for authorities, the Leitweg-ID. | Set invoice.buyer_reference; check the format in the Leitweg-ID guide. |
BR-DE-1 | Payment instructions (BG-16) are missing — XRechnung requires them. | Add invoice.payment; for a SEPA transfer an IBAN is enough. |
BR-DE-2 | Seller contact details (BG-6) are missing. | Set a contact person or department in invoice.seller.contact. |
BR-DE-16 | Neither a VAT identifier (BT-31) nor a tax registration number (BT-32) is present. | Set invoice.seller.vat_id (e.g. “DE123456789”) or seller.tax_number. |
BR-CO-25 | An amount is due but neither a due date (BT-9) nor payment terms (BT-20) are present. | Set invoice.due_date or invoice.payment_terms. |
BR-CO-10 | The sum of line net amounts (BT-106) does not match the invoice lines. | Omit invoice.totals (normbill computes them exactly) or fix the amount. |
BR-CO-14 | The supplied VAT total does not match the computed tax breakdown. | Omit invoice.totals or correct the amounts. |
BR-CL-01 | type_code 381 (credit note) is not allowed in the UBL Invoice syntax. | Use type_code 384 with negative quantities — or a CII format (ZUGFeRD, Factur-X) where 381 is valid. |
The Leitweg-ID (the most common case) has its own guide with a live format check.
What is the fastest way to fix a finding?
- Checking existing XML: the free validator returns the same KoSIT report — with a plain-language explanation and fix per finding, no account needed.
- Generating through the API: when a rule fails, the 422 names the path in your request (e.g.
invoice.buyer_reference), the rule id and a concrete fix; every finding links its rule page. - Looking things up: every rule has its own page under /docs/rules — with a German explanation, the mapped JSON field and the official sources.