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
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.
- Two documents are rejected with no reason given
- With no specification identifier — 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.
- 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.
| Document | KoSIT reports | Mustang reports |
|---|---|---|
| br-02-missing-invoice-number | cvc-complex-type.2.4.a | BR-02 |
| br-03-missing-issue-date | cvc-complex-type.2.4.a | BR-03 |
| br-16-no-invoice-line | cvc-complex-type.2.4.b | BR-16, BR-S-01, BR-S-08, BR-CO-10 |
| br-de-17-invalid-type-code | BR-CL-01 | BR-CL-01, BR-DE-17 |
| schema-invalid-element-order | cvc-complex-type.2.4.a | nothing |
| cii-br-02-missing-invoice-number | cvc-complex-type.2.4.a | BR-02 |
| cii-br-de-17-invalid-type-code | BR-CL-01 | BR-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
| Condition | UBL reports | CII reports |
|---|---|---|
| BR-01 | nothing | nothing |
| BR-02 | cvc-complex-type.2.4.a | cvc-complex-type.2.4.a |
| BR-16 | cvc-complex-type.2.4.b | BR-16, BR-S-08, BR-CO-10 |
| BR-CO-16 | BR-CO-16 | BR-CO-16 |
| BR-CO-15 | BR-CO-15, BR-CO-16 | BR-CO-15, BR-CO-16 |
| BR-CO-13 | BR-CO-15, BR-CO-13 | BR-CO-15, BR-CO-13 |
| BR-DE-2 | BR-DE-2 | BR-DE-2 |
| BR-DE-15 | BR-DE-15 | BR-DE-15 |
| BR-DE-17 | BR-CL-01 | BR-CL-01 |
Every document
Validated with NormAPI · v2026-08-31
| Document | Built for | Reported |
|---|---|---|
| valid-ubl-standardUnmodified XRechnung 3.0 UBL invoice. The control. | - | BR-DE-TMP-32 |
| br-01-missing-customizationSpecification identifier (CustomizationID) removed. | BR-01 | nothing |
| br-02-missing-invoice-numberInvoice number removed. | BR-02 | cvc-complex-type.2.4.a |
| br-03-missing-issue-dateIssue date removed. | BR-03 | cvc-complex-type.2.4.a |
| br-06-missing-seller-nameSeller registration name removed. | BR-06 | BR-06 |
| br-08-missing-seller-addressSeller postal address removed entirely. | BR-08 | BR-08 |
| br-16-no-invoice-lineBoth invoice lines removed; totals left untouched. | BR-16 | cvc-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-10 | BR-CO-10, BR-CO-13 |
| br-co-13-tax-exclusive-wrongNet total stated as 300.00 instead of 314.86. | BR-CO-13 | BR-CO-15, BR-CO-13 |
| br-co-15-tax-inclusive-wrongGross total stated as 350.00 instead of 336.90. | BR-CO-15 | BR-CO-15, BR-CO-16 |
| br-co-16-payable-wrongAmount due for payment stated as 300.00 instead of 336.90. | BR-CO-16 | BR-CO-16 |
| br-s-08-vat-amount-wrongVAT amount for the 7% category stated as 25.00 instead of 22.04. | BR-S-08 | BR-CO-14, BR-CO-17, BR-S-09 |
| br-de-1-missing-payment-meansPaymentMeans removed — no payment instruction at all. | BR-DE-1 | BR-DE-1 |
| br-de-2-missing-seller-contactSeller contact block removed. | BR-DE-2 | BR-DE-2 |
| br-de-15-missing-buyer-referenceBuyer reference (Leitweg-ID) removed. | BR-DE-15 | BR-DE-15 |
| br-de-17-invalid-type-codeInvoice type code set to 999, which is outside the permitted list. | BR-DE-17 | BR-CL-01 |
| br-de-21-wrong-customizationSpecification identifier replaced with the Peppol BIS one. | BR-DE-21 | nothing |
| schema-invalid-element-orderWell formed, but IssueDate sits after InvoiceTypeCode, violating the UBL sequence. | XSD | cvc-complex-type.2.4.a |
| not-well-formedTruncated mid-document; the root element is never closed. | WELLFORMED | nothing |
| 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-01 | nothing |
| cii-br-02-missing-invoice-numberInvoice number removed. Twin of br-02-missing-invoice-number. | BR-02 | cvc-complex-type.2.4.a |
| cii-br-16-no-invoice-lineThe only invoice line removed. Twin of br-16-no-invoice-line. | BR-16 | BR-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-16 | BR-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-15 | BR-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-13 | BR-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-2 | BR-DE-2 |
| cii-br-de-15-missing-buyer-referenceBuyer reference (Leitweg-ID) removed. Twin of br-de-15-missing-buyer-reference. | BR-DE-15 | BR-DE-15 |
| cii-br-de-17-invalid-type-codeInvoice type code set to 999. Twin of br-de-17-invalid-type-code. | BR-DE-17 | BR-CL-01 |
Download the data
CC BY 4.0. Attribution: NormAPI, normapi.de.
NormAPI provides technical validation, not tax or legal advice.