The short answer
BR-05 fails when the document root has no cbc:DocumentCurrencyCode, or has one that is empty or holds only whitespace. Add the element with the ISO 4217 code of the currency the invoice is issued in, such as GBP.
Expect a long list of findings from this one omission. Peppol compares the currencyID of every amount with this element, so while it is missing PEPPOL-EN16931-R051 is reported once per amount, even where the attribute is correct.
What the rule checks
The rule runs once on the Invoice or CreditNote root and looks for a cbc:DocumentCurrencyCode child whose text is not blank once whitespace is stripped. An absent element, an empty one and one holding only spaces all fail it.
Only the presence of a value is tested here. Whether that value is a real currency code is left to BR-CL-04: when tried, gbp passed this rule and was reported by BR-CL-04 instead.
The UBL schema treats the element as optional, so a document without it passes the XSD layer and the gap is left to the EN 16931 layer. When tried, an empty element and one holding a single space each reported BR-CL-04, BR-CO-15 and PEPPOL-EN16931-R008 besides this rule, and PEPPOL-EN16931-R051 on every amount.
The currencyID attributes on the amounts do not stand in for the element. The recorded example still carries GBP on all thirteen amounts and fails.
| Term | Meaning | UBL element |
|---|---|---|
| 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:
- The currency is held on the customer or ledger record, and the export reads it from the invoice header, where it is null.
- A system that only ever invoices in one currency has no currency field at all, and the template writes
currencyID="GBP"on the amounts as a literal without an element for the document currency. - The serialiser skips null values, or writes an empty element for them, and the currency field was null for this invoice.
- The code is written to
cbc:TaxCurrencyCode, the VAT accounting currency, instead ofcbc:DocumentCurrencyCode.
How to fix it
- Take the currency from the transaction: the currency the prices were agreed in and the amounts are expressed in. Do not fall back to the seller home currency if the invoice was raised in another.
- Write it as the upper-case ISO 4217 alphabetic code to
cbc:DocumentCurrencyCodedirectly under the root: after the type code and anycbc:Noteorcbc:TaxPointDate, and beforecbc:TaxCurrencyCode,cbc:AccountingCostandcbc:BuyerReference. When tried, the element placed aftercbc:BuyerReferencefailed the XSD layer. - Check that every amount carries the same code in
currencyID, character for character. Only the VAT total in a separate accounting currency may differ. - Make the currency a required field where invoices are created, so an invoice without one cannot reach the export.
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: no currency code between the type code and the buyer reference, while the amounts still say GBP
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:BuyerReference>BUYER-REF-001</cbc:BuyerReference>
<!-- parties and tax total omitted from this fragment -->
<cac:LegalMonetaryTotal>
<cbc:LineExtensionAmount currencyID="GBP">25.00</cbc:LineExtensionAmount>
<cbc:TaxExclusiveAmount currencyID="GBP">25.00</cbc:TaxExclusiveAmount>
<cbc:TaxInclusiveAmount currencyID="GBP">30.00</cbc:TaxInclusiveAmount>
<!-- allowance, charge, prepaid and rounding totals omitted from this fragment -->
<cbc:PayableAmount currencyID="GBP">30.00</cbc:PayableAmount>
</cac:LegalMonetaryTotal>Fragment of the corrected invoice: the currency code is present, and the amounts are unchanged
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>GBP</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>BUYER-REF-001</cbc:BuyerReference>The corrected invoice has cbc:DocumentCurrencyCode with the value GBP between the type code and the buyer reference; the failing one has no such element, and nothing else differs. The failing document also reports PEPPOL-EN16931-R051 thirteen times, once for each amount in the tax total, the monetary totals and the line: that Peppol rule requires each currencyID to equal the document currency code, and with no code to compare against even the correct GBP attributes fail. Adding the element clears all fourteen findings.
What the validator reported
- The failing invoice reports BR-05 and 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
InvoiceandCreditNotealike; the element has the same name and position in both. When tried, a credit note without it reportedBR-05andPEPPOL-EN16931-R051on every amount, just as the invoice does. - While the code is missing,
BR-CO-15has no document currency to find the VAT total by and passes whatever the totals say. When tried with a total with VAT one pound too high,BR-CO-15stayed silent, and of the totals checks onlyBR-CO-16reported anything. Validate again after adding the code before trusting the totals. - Writing the currency to
cbc:TaxCurrencyCodeinstead does not help. That element declares a separate VAT accounting currency; when tried, it leftBR-05and everyPEPPOL-EN16931-R051finding in place and addedPEPPOL-EN16931-R054andPEPPOL-EN16931-R055.
Related rules
- BR-CL-04 checks that the currency code, once present, is a valid ISO 4217 code
- PEPPOL-EN16931-R051 compares the currencyID of each amount with this code, and fails on every amount while it is missing
- BR-CO-15 locates the VAT total by the document currency, so it cannot check the total with VAT until this code exists
- BR-CL-03 checks the currency code written on each amount
- 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-05 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.
