# BR-O-06: Remove the VAT rate from a document level allowance that is not subject to VAT

A discount or other document-level allowance in category `O` takes no `cbc:Percent` at all, so an allowance rate of `0` in `O` is rejected.

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

## The short answer

`BR-O-06` fails when a `cac:AllowanceCharge` with `cbc:ChargeIndicator` `false` has a `cac:TaxCategory` of `O` that contains `cbc:Percent`. The recorded example gives the `Loyalty discount` of 5.00 a rate of `0`. Delete that element and keep `cbc:ID` and `cac:TaxScheme` as they are.

For a Zero rated or exempt allowance the rate element is how it says 0. For `O` the absence of the element is the statement, just as the `O` breakdown in the recorded example carries none.

## What the rule checks

Every allowance whose tax category is `O` under the `VAT` scheme is tested, and the finding points at that `cac:TaxCategory`. Nothing ties the rule to the document root, so a line-level allowance counts too: when tried, one in `O` with a rate of `0` reported this rule at the line, with the warning `UBL-CR-558` for a tax category on a line allowance.

Only the presence of the element matters. The recorded `0` fails, and when tried a rate of `20` on the same loyalty discount gave the same single finding.

Writing the element empty is no way out: an empty `cbc:Percent` in the discount's tax category failed the XSD layer when tried, so no business rule ran.

This rule reads allowances only. An `O` charge with a rate is reported by `BR-O-07`, and an `O` line with one by `BR-O-05`.

| Term | Meaning | UBL element |
|---|---|---|
| BT-95 | Document level allowance VAT category code | `cac:AllowanceCharge[cbc:ChargeIndicator = false]/cac:TaxCategory/cbc:ID` |
| BT-96 | Document level allowance VAT rate | `cac:AllowanceCharge[cbc:ChargeIndicator = false]/cac:TaxCategory/cbc:Percent` |

## How an integration ends up here

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

- The allowance serialiser writes a rate for every category and stores zero for categories without VAT.
- The discount was first set up as Zero rated with a rate of 0, and later moved to `O` by changing only its code.
- The source system cannot hold an empty rate on an allowance and sends 0 in its place.

## How to fix it

1. Make sure the allowance really belongs in `O`: it should reduce amounts that are themselves not subject to VAT, as the line of 25.00 is in the recorded example.
2. Delete `cbc:Percent` from the allowance's `cac:TaxCategory`, leaving `cbc:ID` `O` followed directly by `cac:TaxScheme`.
3. Leave the amounts as they are. The allowance still takes the `O` taxable amount from 25.00 to 20.00, with or without the rate element.
4. In the serialiser, write the allowance rate for every category except `O`.

## 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 loyalty discount states a rate of 0

```xml
<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>
    <cbc:Percent>0</cbc:Percent>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:TaxCategory>
</cac:AllowanceCharge>
```

Fragment of the corrected invoice: the O loyalty discount has no rate element

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

The failing invoice has `cbc:Percent` `0` between `cbc:ID` and `cac:TaxScheme` in the tax category of the `Loyalty discount`; in the corrected invoice that element is absent. Nothing else differs, and the failing document reports only `BR-O-06`, located at the `cac:TaxCategory` of the first `cac:AllowanceCharge`.

### What the validator reported

- The failing invoice reports **BR-O-06**. The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.com/finance/rule-examples/BR-O-06-invalid.xml)
  - [Download the corrected XML](https://ironfang.com/finance/rule-examples/outside-scope-allowance-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`, where the allowance has the same shape. Rewritten as a credit note, the failing invoice reported this rule alone when tried.
- Allowances in other nil-VAT categories work the other way: a Zero rated or exempt allowance needs a rate of 0 (`BR-Z-06`, `BR-E-06`), so moving an allowance between those categories and `O` means adding or removing the element.
- The same allowance, while in `O`, also rules out VAT identifiers under `BR-O-03` and is deducted in the `O` taxable amount checked by `BR-O-08`.

## Related rules

- [BR-O-05 forbids the same rate element on a line that is not subject to VAT](https://ironfang.com/docs/finance/rules/BR-O-05.md)
- [BR-O-07 forbids it on a document level charge in category O](https://ironfang.com/docs/finance/rules/BR-O-07.md)
- [BR-Z-06 requires the rate of 0 on a Zero rated allowance that this rule forbids for O](https://ironfang.com/docs/finance/rules/BR-Z-06.md)
- [BR-O-03 forbids VAT identifiers on a document with a not subject to VAT allowance](https://ironfang.com/docs/finance/rules/BR-O-03.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-28.1: source checked 2026-09-28, explanation last updated 2026-09-28.

[The official definition of BR-O-06](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-O-06/) 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.com/docs/finance/rules/BR-O-06)
- [Free Peppol invoice validator](https://ironfang.com/tools/peppol-validator)
- [Rule index](https://ironfang.com/docs/finance/rules.md)
- [Ironfang Finance API docs](https://ironfang.com/docs/finance)
- The same rule is available to MCP clients as the tool `finance.rule.get` on https://mcp.ironfang.com/mcp
