Skip to content

BR-O-10: Add the not subject to VAT reason to the VAT breakdown

A VAT breakdown in category O must say that the amount is not subject to VAT: the code VATEX-EU-O, reason text, or both.

EN 16931Fatal: the document is invalidVAT

The short answer

BR-O-10 fails when the cac:TaxCategory of an O VAT breakdown has no cbc:TaxExemptionReasonCode and no cbc:TaxExemptionReason. Add VATEX-EU-O as the code, Not subject to VAT or the equivalent standard text in the language of the invoice, or both; the corrected invoice sends both.

There is no rate in an O breakdown to anchor on. The reason elements come straight after cbc:ID and before cac:TaxScheme.

What the rule checks

Each cac:TaxCategory with cbc:ID of O and scheme VAT inside cac:TaxTotal/cac:TaxSubtotal is tested on its own, and a finding points at that element. A reason code child or a reason text child satisfies it.

One of the two is plenty. When tried, the corrected invoice stayed valid with only VATEX-EU-O, and again with only the text.

Wording is not inspected. The text Outside the scope of VAT passed, and so did the unrelated code VATEX-EU-132, with no finding on any layer.

Peppol ties some codes to their own categories. On an O breakdown, VATEX-EU-IC reported PEPPOL-EN16931-P0106, VATEX-EU-G reported PEPPOL-EN16931-P0104 and VATEX-EU-AE reported PEPPOL-EN16931-P0107 when tried; VATEX-EU-O on an exempt breakdown reported PEPPOL-EN16931-P0105.

An empty cbc:TaxExemptionReason gets past this rule and is caught by PEPPOL-EN16931-R008, which is what happened when tried.

TermMeaningUBL element
BT-118VAT category codecac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:ID
BT-120VAT exemption reason textcac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:TaxExemptionReason
BT-121VAT exemption reason codecac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:TaxExemptionReasonCode

How an integration ends up here

Possible causes, from the shape of the rule rather than from measured usage:

  • Reason fields are generated only for exempt breakdowns, and O goes through a separate branch that writes the category and nothing more.
  • The source system gives out-of-scope amounts no tax code, so there is nowhere to hold a reason.
  • The O breakdown was modelled on the Zero rated one, which carries no reason, and the reason fields were never added.
  • The reason is recorded against the line in the source data and not carried into the breakdown.

How to fix it

  1. Confirm that the amounts are really outside the scope of VAT and that the whole document is, since O cannot share a document with other categories.
  2. In the cac:TaxCategory of the O breakdown, add cbc:TaxExemptionReasonCode with VATEX-EU-O, cbc:TaxExemptionReason with Not subject to VAT or its standard translation, or both.
  3. Put them after cbc:ID and before cac:TaxScheme, with the code ahead of the text. An O breakdown needs no cbc:Percent to sit between them.
  4. Attach the reason to the O category in the mapping, so that every not subject to VAT breakdown is written with it.

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 O breakdown holds only the category and the scheme

<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>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:TaxCategory>
</cac:TaxSubtotal>

Fragment of the corrected invoice: code and text between the category and the scheme

<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>
    <cbc:TaxExemptionReasonCode>VATEX-EU-O</cbc:TaxExemptionReasonCode>
    <cbc:TaxExemptionReason>Not subject to VAT</cbc:TaxExemptionReason>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:TaxCategory>
</cac:TaxSubtotal>

The corrected invoice carries cbc:TaxExemptionReasonCode VATEX-EU-O and cbc:TaxExemptionReason Not subject to VAT in the O tax category; in the failing invoice that category holds only cbc:ID and cac:TaxScheme. The rest of the two documents is identical, and BR-O-10 is the one finding the failing document reports.

What the validator reported

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 Invoice and CreditNote. Rewritten as a credit note, the failing invoice reported this rule at the same breakdown when tried.
  • Only O breakdowns under the VAT scheme are in scope. BR-E-10, BR-AE-10, BR-IC-10 and BR-G-10 are the matching rules for exempt, reverse-charge, intra-community and export breakdowns.
  • A reason on the breakdown does not settle the other O rules: the document must still have no VAT identifiers under BR-O-02 and no other categories under BR-O-11.

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-O-10 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.