Validator comparison: same defect, different answers

Twenty-nine XRechnung documents, each exactly one documented change away from the same valid invoice, run through two independent validators. The dataset is CC BY 4.0 — check it, disagree with it.

29 documents · Rule set v2026-08-31

Measured and checked against the official KoSIT validator by Dmytro Yalanskyi, NormAPI.

Why this exists

Your software says the invoice is fine. Your customer’s system says it is not. Both cite the same rule set, and nobody can settle it, because there is no public dataset either side can be measured against.

This is that dataset. Every document differs from the control in exactly one documented way, generated by a script rather than written by hand. When two validators disagree about a document, the disagreement is about that one change and nothing else.

Method

One base invoice, one mutation per case, applied by corpus/build.py. The results file keeps what a document was built to trip separate from what a validator actually reported — a dataset that asserts its own results proves nothing.

What the first run shows

Four documents never reach the business rules
Remove a mandatory field — the invoice number, the issue date, every line — and the document is already invalid against the UBL schema. What comes back is cvc-complex-type.2.4.a, and BR-02 never gets to fire. A comparison that scores "did it report BR-02?" will call this a miss when it is nothing of the sort.
Three documents are rejected with no reason given
With no specification identifier — in UBL and in CII alike — or a Peppol BIS one where an XRechnung one belongs, no scenario matches. So no schema is applied and no rule is evaluated. The answer is "not acceptable" with an empty findings list: refused, without anything being named. That is exactly what a supplier whose software emits Peppol BIS to a German recipient runs into. The table says "nothing" a fourth time, against the document that is not well-formed XML — there for the obvious reason that the file cannot be read at all.
Mustang names the rule where KoSIT reports only the schema
With the invoice number gone, KoSIT reports cvc-complex-type.2.4.a and stops. Mustang reports BR-02 — same invoice, same norm, but a sentence the sender can act on. It runs the other way too: the out-of-order element is caught by KoSIT and missed by Mustang entirely. Neither is uniformly better; they are strict in different places.
The same missing line, two entirely different answers
An invoice with no lines reports cvc-complex-type.2.4.b in UBL — a schema error nobody can act on. The same document in CII reports BR-16, BR-CO-10 and BR-S-08: three named rules in plain language. Same defect, same norm, very different usefulness.

KoSIT against Mustang

Two independent implementations of the same rule set, the same 29 documents. They agree on 22 and disagree on 7 — and the differences cut both ways.

7/29 disagree · Only the cases where they differ.

DocumentKoSIT reportsMustang reports
br-02-missing-invoice-numbercvc-complex-type.2.4.aBR-02
br-03-missing-issue-datecvc-complex-type.2.4.aBR-03
br-16-no-invoice-linecvc-complex-type.2.4.bBR-16, BR-S-01, BR-S-08, BR-CO-10
br-de-17-invalid-type-codeBR-CL-01BR-CL-01, BR-DE-17
schema-invalid-element-ordercvc-complex-type.2.4.anothing
cii-br-02-missing-invoice-numbercvc-complex-type.2.4.aBR-02
cii-br-de-17-invalid-type-codeBR-CL-01BR-CL-01, BR-DE-17

KoSIT v2026-08-31 · Mustang 2.17.0

UBL against CII: same defect, two syntaxes

Nine cases exist twice, once in UBL and once in CII, carrying the same change. A norm that demands the same of both syntaxes should report the same thing nine times.

1/9 differs

ConditionUBL reportsCII reports
BR-01nothingnothing
BR-02cvc-complex-type.2.4.acvc-complex-type.2.4.a
BR-16cvc-complex-type.2.4.bBR-16, BR-S-08, BR-CO-10
BR-CO-16BR-CO-16BR-CO-16
BR-CO-15BR-CO-15, BR-CO-16BR-CO-15, BR-CO-16
BR-CO-13BR-CO-15, BR-CO-13BR-CO-15, BR-CO-13
BR-DE-2BR-DE-2BR-DE-2
BR-DE-15BR-DE-15BR-DE-15
BR-DE-17BR-CL-01BR-CL-01

Every document

Validated with NormAPI · v2026-08-31

DocumentBuilt forReported
valid-ubl-standardUnmodified XRechnung 3.0 UBL invoice. The control.-BR-DE-TMP-32
br-01-missing-customizationSpecification identifier (CustomizationID) removed.BR-01nothing
br-02-missing-invoice-numberInvoice number removed.BR-02cvc-complex-type.2.4.a
br-03-missing-issue-dateIssue date removed.BR-03cvc-complex-type.2.4.a
br-06-missing-seller-nameSeller registration name removed.BR-06BR-06
br-08-missing-seller-addressSeller postal address removed entirely.BR-08BR-08
br-16-no-invoice-lineBoth invoice lines removed; totals left untouched.BR-16cvc-complex-type.2.4.b
br-co-10-line-sum-wrongSum of line net amounts stated as 300.00 instead of 314.86.BR-CO-10BR-CO-10, BR-CO-13
br-co-13-tax-exclusive-wrongNet total stated as 300.00 instead of 314.86.BR-CO-13BR-CO-15, BR-CO-13
br-co-15-tax-inclusive-wrongGross total stated as 350.00 instead of 336.90.BR-CO-15BR-CO-15, BR-CO-16
br-co-16-payable-wrongAmount due for payment stated as 300.00 instead of 336.90.BR-CO-16BR-CO-16
br-s-08-vat-amount-wrongVAT amount for the 7% category stated as 25.00 instead of 22.04.BR-S-08BR-CO-14, BR-CO-17, BR-S-09
br-de-1-missing-payment-meansPaymentMeans removed — no payment instruction at all.BR-DE-1BR-DE-1
br-de-2-missing-seller-contactSeller contact block removed.BR-DE-2BR-DE-2
br-de-15-missing-buyer-referenceBuyer reference (Leitweg-ID) removed.BR-DE-15BR-DE-15
br-de-17-invalid-type-codeInvoice type code set to 999, which is outside the permitted list.BR-DE-17BR-CL-01
br-de-21-wrong-customizationSpecification identifier replaced with the Peppol BIS one.BR-DE-21nothing
schema-invalid-element-orderWell formed, but IssueDate sits after InvoiceTypeCode, violating the UBL sequence.XSDcvc-complex-type.2.4.a
not-well-formedTruncated mid-document; the root element is never closed.WELLFORMEDnothing
valid-cii-standardUnmodified XRechnung 3.0 CII invoice. The second control.-BR-DE-TMP-32
cii-br-01-missing-customizationSpecification identifier removed. Twin of br-01-missing-customization.BR-01nothing
cii-br-02-missing-invoice-numberInvoice number removed. Twin of br-02-missing-invoice-number.BR-02cvc-complex-type.2.4.a
cii-br-16-no-invoice-lineThe only invoice line removed. Twin of br-16-no-invoice-line.BR-16BR-16, BR-S-08, BR-CO-10
cii-br-co-16-payable-wrongAmount due for payment stated as 300.00 instead of 336.90. Twin of br-co-16-payable-wrong.BR-CO-16BR-CO-16
cii-br-co-15-tax-inclusive-wrongGross total stated as 350.00 instead of 336.90. Twin of br-co-15-tax-inclusive-wrong.BR-CO-15BR-CO-15, BR-CO-16
cii-br-co-13-tax-exclusive-wrongNet total stated as 300.00 instead of 314.86. Twin of br-co-13-tax-exclusive-wrong.BR-CO-13BR-CO-15, BR-CO-13
cii-br-de-2-missing-seller-contactSeller contact block removed. Twin of br-de-2-missing-seller-contact.BR-DE-2BR-DE-2
cii-br-de-15-missing-buyer-referenceBuyer reference (Leitweg-ID) removed. Twin of br-de-15-missing-buyer-reference.BR-DE-15BR-DE-15
cii-br-de-17-invalid-type-codeInvoice type code set to 999. Twin of br-de-17-invalid-type-code.BR-DE-17BR-CL-01

Download the data

CC BY 4.0. Attribution: NormAPI, normapi.de.

How to cite this measurement

NormAPI (2026). Validator comparison: same defect, different answers. https://normapi.com/en/study/validator-comparison

Measured against the rule-set release named above. KoSIT updates the rule set roughly twice a year; we repeat the run with each release and carry the date here forward. If the version above is older than the one currently live, this run has not been redone yet.

The same question from the other side: eleven free online validators, the same invoice, one day

Deutsche Fassung

NormAPI provides technical validation, not tax or legal advice.