The short answer
BR-CL-03 fails when the currencyID attribute of an amount is not a code on the ISO 4217 alphabetic list. The finding location is the amount element; set the attribute to the three-letter code of the invoice currency, the same value as cbc:DocumentCurrencyCode.
The UKP in the recorded example looks like a code for pounds sterling but is not one; the ISO code is GBP. Two Peppol rules examine the same attribute, so one bad value produces three findings.
What the rule checks
It checks the currencyID of every cbc:Amount, cbc:BaseAmount, cbc:PriceAmount, cbc:TaxAmount, cbc:TaxableAmount and cbc:LineExtensionAmount, and of the other totals in cac:LegalMonetaryTotal, wherever they appear. Unlike the decimals limit, it covers the item price too.
The attribute is trimmed and then looked up in a fixed list of codes, case-sensitively. When tried, gbp, the numeric code 826, a pound sign and an empty attribute each failed.
Surrounding spaces are forgiven here but not elsewhere. When tried, a leading space before GBP passed this rule and was still reported by PEPPOL-EN16931-CL007 and PEPPOL-EN16931-R051, which compare the attribute exactly as written.
Any listed code passes, including one that differs from the document currency. Matching the invoice currency is the business of PEPPOL-EN16931-R051.
The attribute is required by the UBL schema. When tried, an amount without currencyID failed the XSD layer and this rule was never reached.
| Term | Meaning | UBL element |
|---|---|---|
| - | Currency of an amount (the currencyID attribute) | currencyID on each amount element, for example cac:InvoiceLine/cac:Price/cbc:PriceAmount/@currencyID |
| BT-5 | Invoice currency code | cbc:DocumentCurrencyCode |
How an integration ends up here
Possible causes, from the shape of the rule rather than from measured usage:
- A currency is typed by hand or held in a free-text field, producing values such as
UKPorSTG. - Currency codes are stored in lower case or as ISO numeric codes and written through unchanged.
- Each kind of amount takes its currency from a different source, and one of them, such as a price list, spells the currency differently.
- A currency symbol from the display layer is used as the attribute value.
How to fix it
- Use the finding location to see which amount carries the bad value, then find where your mapping fills its
currencyID. - Fill every
currencyIDfrom the same source ascbc:DocumentCurrencyCode, so the codes cannot drift apart. - Write the upper-case ISO 4217 alphabetic code, trimmed. Translate numeric codes, symbols and names where the value enters your system.
- The only amount that may carry a different code is the VAT total in the VAT accounting currency, in its own
cac:TaxTotalwithout a breakdown, and that code must matchcbc:TaxCurrencyCode.
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: the price is labelled UKP
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="C62">2</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="GBP">25.00</cbc:LineExtensionAmount>
<!-- item omitted from this fragment -->
<cac:Price>
<cbc:PriceAmount currencyID="UKP">12.5</cbc:PriceAmount>
<cbc:BaseQuantity unitCode="C62">1</cbc:BaseQuantity>
</cac:Price>
</cac:InvoiceLine>Fragment of the corrected invoice: the price is in GBP like every other amount
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="C62">2</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="GBP">25.00</cbc:LineExtensionAmount>
<!-- item omitted from this fragment -->
<cac:Price>
<cbc:PriceAmount currencyID="GBP">12.5</cbc:PriceAmount>
<cbc:BaseQuantity unitCode="C62">1</cbc:BaseQuantity>
</cac:Price>
</cac:InvoiceLine>Only the currencyID on cbc:PriceAmount differs: UKP in the failing invoice, GBP in the corrected one. Three findings share that location. BR-CL-03 is the EN 16931 code list check. PEPPOL-EN16931-CL007 is the Peppol layer check of the same attribute against ISO 4217, so a value that is not a listed code fails both. PEPPOL-EN16931-R051 is reported because UKP is not the document currency GBP; it would fire even for a valid code such as EUR. Correcting the attribute clears all three.
What the validator reported
- The failing invoice reports BR-CL-03,
PEPPOL-EN16931-CL007and PEPPOL-EN16931-R051. 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
InvoiceandCreditNote. When tried, a credit note withUKPon the price reported the same three rules. - The list is the same ISO 4217 snapshot that
BR-CL-04applies to the document currency, so a code that has been withdrawn fails here as well. - The rule looks at one attribute at a time. It does not compare amounts with each other or with the document currency, so a mix of valid codes passes it.
Related rules
- PEPPOL-EN16931-R051 requires each currencyID to equal the document currency code
- BR-CL-04 applies the same code list to the document currency code
- BR-05 requires the document currency code that the attributes should repeat
- Browse every rule in the reference
- Background: Understanding EN 16931 validation errors
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-24.
The official definition of BR-CL-03 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.
