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 XRechnung generate and validate, in both the UBL and CII syntax. It has the final word on conformance. ZUGFeRD / Factur-X and Peppol BIS are checked against structural EN 16931 rules instead, because the pinned KoSIT configuration ships scenarios for the XRechnung CIUS only.

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).
  • Severityerror makes the document non-conformant, warning does 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.
PrefixFamilyTypical cause
BR-DE-*German XRechnung rules (CIUS)Mandatory fields missing: contact, payment, Leitweg-ID
BR-CO-*Calculations & conditionsTotals do not add up, dependent fields missing
BR-DEC-*Decimal precisionMore than two decimal places in amounts
BR-CL-*Code listsDisallowed code, e.g. type_code 381 in UBL
BR-S-*, BR-AE-*, …VAT categoriesTax category inconsistent with rates or exemptions
UBL-SR-*, UBL-CR-*UBL bindingStructure of the UBL XML
XSDXML schemaThe XML does not match the schema

Every family lives in the rule reference — the rules you actually hit are documented individually in English and German, the long tail is explained at family level.

Eight errors we see most often — cause and fix

RuleWhat the validator objects toFix in the normbill JSON
BR-DE-15The 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-1Payment instructions (BG-16) are missing — XRechnung requires them.Add invoice.payment; for a SEPA transfer an IBAN is enough.
BR-DE-2Seller contact details (BG-6) are missing.Set a contact person or department in invoice.seller.contact.
BR-DE-16Neither 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-25An 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-10The 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-14The supplied VAT total does not match the computed tax breakdown.Omit invoice.totals or correct the amounts.
BR-CL-01type_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.

Where next?

Validator · Playground · Rule reference · 2027 checklist

Deutsche Fassung →

Spotted something?

Bug, missing feature, wrong validation result — tell us. The page you're on is attached automatically; email optional.