What BR-DE-21 checks
BR-DE-21 requires that the specification identifier, BT-24, syntactically match the identifier of the XRechnung standard. In UBL that is cbc:CustomizationID, in CII ram:GuidelineSpecifiedDocumentContextParameter/ram:ID. The value is the contract note of the whole document: it declares which rulebook the invoice claims to satisfy. The German CIUS refuses to validate a document that claims to be something else, which makes BR-DE-21 the first rule to fire on profile mix-ups.
Layer and formats
The finding carries "layer": "cius" and appears when validating against the XRechnung profile, whether the syntax is UBL or CII and whether the document is pure XML or the embedded half of a ZUGFeRD / Factur-X hybrid declaring the XRechnung profile.
Why it fails in practice
- Version drift. The document declares
xrechnung_2.3or older. XRechnung 3.0 has been the current version since February 2024, and strict receivers reject superseded declarations. - Wrong CIUS entirely. The generator stamps the Peppol BIS or a Factur-X identifier because the same pipeline serves several markets, and the German B2G branch never overrides it.
- A hand-edited URN. One typo in the long identifier string, a stray space, wrong case, or a missing
#compliant#segment, and the syntactic match fails.
How to fix it
Emit the current XRechnung CustomizationID verbatim:
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</cbc:CustomizationID>
In an InvoiceXML create request the field is invoice.specificationId, and you normally leave it out: /v1/create/xrechnung stamps the current identifier itself, and switches to the next KoSIT release server-side on its effective date.
The raw rejection vs the InvoiceXML finding
The Schematron report, in the words of the German rule:
<svrl:failed-assert id="BR-DE-21" flag="warning"
location="/*:Invoice[namespace-uri()='urn:oasis:names:specification:ubl:schema:xsd:Invoice-2'][1]">
<svrl:text>[BR-DE-21] Das Element "Specification identifier" (BT-24)
soll syntaktisch der Kennung des Standards XRechnung entsprechen.</svrl:text>
</svrl:failed-assert>
Note the flag="warning": KoSIT phrases the rule as a should ("soll"), so the finding lands among the warnings of a report rather than the fatal errors. Receivers still match the identifier at intake, which is why treating the warning as binding is the safe engineering call.
The same failure as an InvoiceXML finding:
{
"rule": "BR-DE-21",
"layer": "cius",
"line": null,
"message": "The specification identifier must match the XRechnung standard URI. Ensure the XRechnung profile is used.",
"btCodes": ["BT-24"],
"fields": ["specificationId"],
"raw": "[BR-DE-21] CIUS: Das Element \"Specification identifier\" (BT-24) soll syntaktisch der Kennung des Standards XRechnung entsprechen."
}
Your integration never parses rule codes or translates German rule text: the message is ready for end users, fields names the input to highlight, and the stable rule key lets clients localize messages themselves if they prefer.
Check or generate XRechnung documents
Drop a document into the XRechnung validator to see which identifier it declares and which rules object. Generating with POST /v1/create/xrechnung makes BR-DE-21 a non-issue: the current CustomizationID is stamped for you, with nothing to monitor or redeploy when KoSIT publishes the next version. Background reading: the XRechnung API toolkit.
Related rules and identifiers
- The XRechnung 3.0 CustomizationID, both spellings of the identifier this rule checks
- BR-01, the core rule that a specification identifier exists at all
- BR-DE-15, the mandatory buyer reference (Leitweg-ID)
- urn:cen.eu:en16931:2017, the stem and #compliant# grammar behind the identifier