On this page
The short answer
PEPPOL-EN16931-R004 fails when cbc:CustomizationID is absent, empty, or holds anything other than the Peppol BIS Billing 3.0 identifier. Write urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0 as the first child of the root, character for character.
When the element is missing altogether the document also reports BR-01, the EN 16931 rule that a specification identifier must exist. When the element is present with a different value, such as the bare urn:cen.eu:en16931:2017, only PEPPOL-EN16931-R004 is reported: EN 16931 is satisfied by any non-empty identifier, Peppol is not.
What the rule checks
The rule reads the text of cbc:CustomizationID under the document root, ignores leading and trailing whitespace, and requires it to begin with the Peppol BIS Billing 3.0 identifier. It also rejects any value that contains two colons in a row.
The comparison is case-sensitive. The same identifier in upper case fails.
Because the test is on how the value begins, an identifier that continues after the Peppol value with a further # segment is not reported by this rule. That is not a reason to append anything: for ordinary Billing, send the identifier exactly.
Identifiers for other specifications fail: plain EN 16931, XRechnung, the Peppol self-billing identifier, and the business process identifier placed in the wrong element were all reported when tried.
| Term | Meaning | UBL element |
|---|---|---|
| BT-24 | Specification identifier | cbc:CustomizationID |
How an integration ends up here
Possible causes, from the shape of the rule rather than from measured usage:
- The mapping was written for plain EN 16931 or for another CIUS and the identifier was carried over unchanged.
- The identifier is a configuration value and the environment being tested has it blank, so the element is dropped.
- The values for
cbc:CustomizationIDandcbc:ProfileIDwere swapped or merged. - The identifier was retyped by hand and differs by case, a missing
#compliant#segment, or a stray character.
How to fix it
- Emit
cbc:CustomizationIDas the first child of theInvoiceorCreditNoteroot. The UBL schema requires it to come beforecbc:ProfileID. - Set it to
urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0. Hold the value as a constant in code, copied and not retyped. - Keep
cbc:ProfileIDas a separate element with the business process identifier. The two are different terms with different values. - If the document is really meant for another specification, such as XRechnung, it is outside what this validator supports; do not relabel it as Peppol just to clear the finding. The identifier is a claim about the whole document, and it would then claim a specification it was not built for.
Validate your corrected invoice
Before and after
These are fragments, not complete documents. The complete synthetic documents they come from are linked below.
Fragment of the failing invoice: there is no specification identifier, so the header starts at the business process
<!-- no cbc:CustomizationID in the failing document -->
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>EXAMPLE-INV-001</cbc:ID>
<!-- rest of the document omitted from this fragment -->Fragment of the corrected invoice: the Peppol BIS Billing 3.0 identifier comes first
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>EXAMPLE-INV-001</cbc:ID>
<!-- rest of the document omitted from this fragment -->The corrected document adds the cbc:CustomizationID line; nothing else differs. The failing document reports BR-01 in the EN 16931 layer, because no specification identifier exists at all, and PEPPOL-EN16931-R004 in the Peppol layer, because there is no value to begin with the Peppol identifier. One element clears both. This example is shared with BR-01.
What the validator reported
- The failing invoice reports BR-01 and PEPPOL-EN16931-R004. The corrected document passes every layer with no findings.Download the failing XMLDownload the corrected XML
Recorded on phive 12.1.0 / phive-rules-peppol 4.5.6 / Saxon-HE 12.10, the engine behind the free validator, using synthetic data. A recorded result is regression evidence for these documents; it is not a certification.
Where it applies
- Applies to UBL
InvoiceandCreditNotealike, with the same identifier for both. A credit note with a missing identifier, or a different one, reports the same findings as an invoice does. - An empty
cbc:CustomizationIDreports three rules:BR-01, this rule, andPEPPOL-EN16931-R008for the empty element. - Passing this rule says only that the document claims to be Peppol BIS Billing 3.0. Every other rule still decides whether it is.
Related rules
- BR-01 is the EN 16931 rule that fires with this one when the identifier is missing
- PEPPOL-EN16931-R001 requires the business process identifier that follows it
- PEPPOL-EN16931-R008 is also reported when the identifier element is present but empty
- Browse every rule in the reference
- Background: How Peppol invoice validation actually works
Scope and source
Written for Peppol BIS Billing 3.0.21 (May 2026), EN 16931 1.3.16, as applied to UBL 2.1 Invoice and CreditNote documents. Other profiles, syntaxes and releases can define this identifier differently. Guidance version 2026-09-24.1: source checked 2026-09-24, explanation last updated 2026-09-20.
The official definition of PEPPOL-EN16931-R004 carries the normative wording and test. This page is our explanation of it, not a copy.
Guidance does not change the engine verdict. Fixing this finding does not mean the document passes every layer, and validation does not certify legal or tax compliance or transmit a document over Peppol.

