Automation MCP Server Features Blog Pricing Contact
Validation rule XRechnung CIUS

BR-DE-21

BR-DE-21 is the gatekeeper rule of the German CIUS: the specification identifier (BT-24) must syntactically match the XRechnung standard's identifier. Fail it and the receiver does not even consider the document an XRechnung.

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.3 or 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.

Frequently asked questions

Which BT-24 value passes BR-DE-21 today?

The CustomizationID of the current XRechnung version, for 3.0: urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0. Emitting the identifier of a superseded version is the classic failure, since public-sector receivers validate against the current KoSIT rule set.

I validate a Peppol BIS invoice as XRechnung and get BR-DE-21. Is the file broken?

The file is fine; the profile is wrong. A document declaring the Peppol BIS CustomizationID is not an XRechnung, so the German gatekeeper rule rejects it. Validate it under the Peppol or en16931 profile instead, or generate a real XRechnung if a German authority is the recipient.

Does BR-DE-21 fire for ZUGFeRD files?

Only when you validate them against the XRechnung profile. A ZUGFeRD invoice declaring a Factur-X profile URN in BT-24 is validated against the Factur-X rules; a hybrid declaring the XRechnung profile is checked with the KoSIT rules including BR-DE-21.

What does 'syntactically match' mean exactly?

The rule checks the shape of the string against the XRechnung identifier pattern. Case changes, whitespace, a missing #compliant# segment, or an unknown version suffix all break the match. Treat BT-24 as an exact, copy-pasted constant, never a hand-typed one.