The short answer
PEPPOL-EN16931-R005 fails when cbc:TaxCurrencyCode names the same currency as cbc:DocumentCurrencyCode, and the finding points at cbc:TaxCurrencyCode. If VAT is accounted for in the invoice currency, delete that element; the VAT total in the invoice currency already covers it.
Send cbc:TaxCurrencyCode only when the seller must account for VAT in a different currency, and then add the VAT total in that currency as a tax total of its own.
What the rule checks
The rule runs on cbc:TaxCurrencyCode directly under the root, when there is one, and compares its text with the text of cbc:DocumentCurrencyCode. Leading and trailing spaces are removed first, so a padded GBP against GBP still fails; when tried, that padded code was reported here.
Case is not folded. When tried, gbp on a GBP invoice did not report this rule. It reported BR-CL-05 instead, because gbp is not a valid currency code, along with BR-53, PEPPOL-EN16931-R054 and PEPPOL-EN16931-R055, which all found no accounting-currency total.
When cbc:TaxCurrencyCode is absent the rule has nothing to test. It never judges whether the accounting currency is the right one for the seller, only that it differs from the invoice currency.
| Term | Meaning | UBL element |
|---|---|---|
| BT-6 | VAT accounting currency code | cbc:TaxCurrencyCode |
| 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 export fills
cbc:TaxCurrencyCodefrom the company base currency on every document, including those issued in that same currency. - The mapping copies the invoice currency into
cbc:TaxCurrencyCodebecause both fields are labelled as a currency in the source model. - A template built for foreign-currency invoices, which needs the element, is reused for domestic ones.
How to fix it
- Compare the invoice currency with the currency in which the seller accounts for VAT.
- If they are the same, remove
cbc:TaxCurrencyCode, and remove any extracac:TaxTotalthat was added only to carry VAT in that currency. Without the code, a tax total with no breakdown is itself an error underPEPPOL-EN16931-R054. - If they differ, the code was wrong rather than unnecessary: write the real accounting currency and add a
cac:TaxTotalholding onlycbc:TaxAmountin that currency, whichBR-53requires. - Make the export decide from the two currency settings whether to write the element, instead of writing it on every document.
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: a GBP invoice declares GBP as its VAT accounting currency
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>GBP</cbc:DocumentCurrencyCode>
<cbc:TaxCurrencyCode>GBP</cbc:TaxCurrencyCode>
<cbc:BuyerReference>BUYER-REF-001</cbc:BuyerReference>Fragment of the corrected invoice: the VAT accounting currency is left out
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>GBP</cbc:DocumentCurrencyCode>
<cbc:BuyerReference>BUYER-REF-001</cbc:BuyerReference>The failing invoice has <cbc:TaxCurrencyCode>GBP</cbc:TaxCurrencyCode> after its GBP document currency; the corrected one has no such element and is otherwise identical. The failing document also reports PEPPOL-EN16931-R054, because a declared accounting currency calls for exactly one tax total without a breakdown and this invoice has none. Removing the code clears both. The EN 16931 layer passes: BR-53 finds the existing GBP tax total, whose currency matches the declared code.
What the validator reported
- The failing invoice reports PEPPOL-EN16931-R005 and PEPPOL-EN16931-R054. 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. A credit note withcbc:TaxCurrencyCodeof GBP on a GBP document reported this rule andPEPPOL-EN16931-R054when tried. - Reported by the Peppol layer only; the EN 16931 layer passes the recorded example.
- Adding a second tax total in the invoice currency is no way round it. When tried, that cleared
PEPPOL-EN16931-R054but left this rule and addedBR-CO-15, which expects exactly one VAT total in the invoice currency. - Whether
cbc:DocumentCurrencyCodeitself is a valid code is checked byBR-CL-04.
Related rules
- PEPPOL-EN16931-R054 ties the extra tax total to the accounting currency and is reported alongside this rule
- BR-53 requires the VAT total in the accounting currency when one is genuinely declared
- BR-CL-04 checks the invoice currency code that this rule compares against
- PEPPOL-EN16931-R055 checks the sign of the accounting-currency VAT total
- 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-24.
The official definition of PEPPOL-EN16931-R005 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.
