On this page
The short answer
BR-O-13 fails when the document has an O VAT breakdown and an allowance, a cac:AllowanceCharge with cbc:ChargeIndicator false, whose cac:TaxCategory is in any other category under the VAT scheme. In the recorded invoice the Loyalty discount of 5.00 is coded S at 20 while the line and the breakdown are O. Put the allowance back in O, without a rate, and deduct it in the O taxable amount.
A discount takes the VAT treatment of what it reduces. On an invoice where everything is outside the scope of VAT, a Standard rated discount would be reducing VAT that was never charged.
What the rule checks
After finding an O breakdown, the rule counts cac:TaxCategory elements under the VAT scheme with a cbc:ID other than O inside allowances, wherever those allowances are, and needs the count to be zero. BR-O-11 does not see this case, because no second breakdown exists.
The search reaches below the root. When tried, an allowance of 0.00 inside the O line, with a cac:TaxCategory of S at 20, reported this rule with BR-S-01, BR-S-03 and the warning UBL-CR-558, which advises against a tax category on a line allowance.
Any other category is caught. With the discount coded E at 0 instead, the findings were this rule, BR-E-01 and BR-E-03; coded Z at 0, this rule, BR-Z-01 and BR-Z-03.
Giving the Standard rated discount a breakdown of its own only changes the company this rule keeps: when tried, an S breakdown of -5.00 replaced BR-S-01 with BR-O-11, and this rule and BR-S-03 stayed.
| Term | Meaning | UBL element |
|---|---|---|
| BG-20 | Document level allowances | cac:AllowanceCharge[cbc:ChargeIndicator = false] |
| BT-95 | Document level allowance VAT category code | cac:AllowanceCharge[cbc:ChargeIndicator = false]/cac:TaxCategory/cbc:ID |
| BT-118 | VAT category code | cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:ID |
How an integration ends up here
Possible causes, from the shape of the rule rather than from measured usage:
- Discounts are created from a template that carries the Standard rate, whatever the category of the invoice they are added to.
- The discount copies its category from the seller's default tax code instead of from the lines it reduces.
- A promotion engine outside the invoicing system adds the allowance with its own tax settings.
How to fix it
- Work out which lines the allowance reduces. If they are all in
O, the allowance belongs inOas well. - Change the allowance's
cac:TaxCategory/cbc:IDtoOand delete itscbc:Percent, asBR-O-06requires. - Deduct the allowance in the
Obreakdown: in the recorded example theOtaxable amount goes from 25.00 to 20.00, in line with the totals, which already deduct the discount. - If the allowance really relates to taxable supplies, those supplies and the allowance belong on a separate invoice with their own breakdown.
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 Standard rated loyalty discount on a document whose only breakdown is O
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Loyalty discount</cbc:AllowanceChargeReason>
<cbc:Amount currencyID="GBP">5.00</cbc:Amount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>20</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="GBP">0.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="GBP">25.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="GBP">0.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>O</cbc:ID>
<!-- reason code and text omitted from this fragment -->
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>Fragment of the corrected invoice: the discount is in O and deducted in the O breakdown
<cac:AllowanceCharge>
<cbc:ChargeIndicator>false</cbc:ChargeIndicator>
<cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
<cbc:AllowanceChargeReason>Loyalty discount</cbc:AllowanceChargeReason>
<cbc:Amount currencyID="GBP">5.00</cbc:Amount>
<cac:TaxCategory>
<cbc:ID>O</cbc:ID>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:AllowanceCharge>
<cac:TaxTotal>
<cbc:TaxAmount currencyID="GBP">0.00</cbc:TaxAmount>
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="GBP">20.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="GBP">0.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>O</cbc:ID>
<!-- reason code and text omitted from this fragment -->
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>
</cac:TaxTotal>In the failing invoice the Loyalty discount has cbc:ID S and cbc:Percent 20, and the O taxable amount is 25.00, the line without the discount; the corrected invoice codes the discount O with no rate and deducts it, giving 20.00. The failing breakdown was set to 25.00 so that it matches its own O content and BR-O-08 stays quiet; with the discount recoded alone, that rule joined the findings when tried. The failing document also reports BR-S-01, since the Standard rated allowance has no Standard rated breakdown, and BR-S-03, since a Standard rated allowance needs a seller VAT identifier, a tax registration identifier or a tax representative.
What the validator reported
- The failing invoice reports BR-O-13, BR-S-01 and BR-S-03. 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; the credit note version of the failing invoice reported the same three findings when tried. - Lines and charges have the matching rules
BR-O-12andBR-O-14. Only anObreakdown switches the three on; an allowance inOon a document with noObreakdown is a matter forBR-O-01.
Related rules
- BR-O-14 is the same restriction for document level charges
- BR-O-12 is the same restriction for invoice lines
- BR-S-03 is reported here because a Standard rated allowance needs a seller identifier for VAT or tax
- BR-O-06 applies once the allowance is back in category O, and forbids its rate
- 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-28.1: source checked 2026-09-28, explanation last updated 2026-09-28.
The official definition of BR-O-13 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.

