# 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.

- Layer: EN 16931
- Severity: fatal (the document is invalid)
- Topics: VAT
- Official definition: https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-O-10/
- Explanation last updated: 2026-09-24

## 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.

| Term | Meaning | UBL element |
|---|---|---|
| BT-118 | VAT category code | `cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:ID` |
| BT-120 | VAT exemption reason text | `cac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:TaxExemptionReason` |
| BT-121 | VAT exemption reason code | `cac: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.

## 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

```xml
<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

```xml
<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

- The failing invoice reports **BR-O-10**. The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/BR-O-10-invalid.xml)
  - [Download the corrected XML](https://ironfang.uk/finance/rule-examples/not-subject-valid.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 `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`.

## Related rules

- [BR-E-10 is the reason rule for exempt breakdowns, where the wording has to name the exemption](https://ironfang.uk/docs/finance/rules/BR-E-10.md)
- [BR-IC-10 is the reason rule for intra-community supply breakdowns](https://ironfang.uk/docs/finance/rules/BR-IC-10.md)
- [BR-CL-22 rejects a reason code that is not in the VATEX list](https://ironfang.uk/docs/finance/rules/BR-CL-22.md)
- [BR-O-11 keeps every other VAT category out of a document that has an O breakdown](https://ironfang.uk/docs/finance/rules/BR-O-11.md)

## 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](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/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.

## Links

- [This rule as a web page](https://ironfang.uk/docs/finance/rules/BR-O-10)
- [Free Peppol invoice validator](https://ironfang.uk/tools/peppol-validator)
- [Rule index](https://ironfang.uk/docs/finance/rules.md)
- [Ironfang Finance API docs](https://ironfang.uk/docs/finance)
- The same rule is available to MCP clients as the tool `finance.rule.get` on https://mcp.ironfang.uk/mcp
