# BR-CO-14: Fix a VAT total that does not match the VAT breakdown

The VAT total of a tax total must equal the sum of the tax amounts in its VAT breakdowns, rounded to two decimals.

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

## The short answer

`BR-CO-14` fails when `cac:TaxTotal/cbc:TaxAmount` is not the sum of the `cbc:TaxAmount` values in the `cac:TaxSubtotal` elements of the same `cac:TaxTotal`. Add the breakdown amounts, round to two decimals, and send that as the VAT total.

The rule does not say which side is wrong, only that the two must agree as sent. If the source system arrives at its VAT total another way, for example by summing VAT per line, the breakdown amounts still have to add up to that total, and each of them stays subject to `BR-CO-17`.

## What the rule checks

The rule runs on each `cac:TaxTotal` directly under the document root and compares its own `cbc:TaxAmount` with the `cbc:TaxAmount` of its `cac:TaxSubtotal` children. A breakdown with 0.00 VAT, such as a zero-rated category, simply adds nothing.

The sum is rounded to two decimals and compared exactly. A VAT total of 11.71 against a breakdown adding up to 11.70 fails.

A `cac:TaxTotal` with no `cac:TaxSubtotal` is skipped. That is how the second tax total, carrying only the VAT amount in the VAT accounting currency, passes this rule.

The rule does not recalculate VAT. Whether each breakdown amount fits its taxable amount and rate is the business of `BR-CO-17`, and that check tolerates a difference of less than one currency unit. `BR-CO-14` has no such slack.

| Term | Meaning | UBL element |
|---|---|---|
| BT-110 | Invoice total VAT amount | `cac:TaxTotal/cbc:TaxAmount` |
| BT-117 | VAT category tax amount | `cac:TaxTotal/cac:TaxSubtotal/cbc:TaxAmount` |

## How an integration ends up here

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

- VAT is calculated and rounded per line and those figures are summed for the total, while the breakdown is calculated per category from the category taxable amount. The two can differ by a penny or more.
- The VAT total is copied from the source system and the breakdown is recalculated during mapping.
- A VAT category present in the source total has no `cac:TaxSubtotal` in the XML, or a breakdown is emitted twice.
- A later adjustment, such as a document-level charge, updated the breakdown but not the stored VAT total.

## How to fix it

1. Build the VAT breakdown first: one `cac:TaxSubtotal` per VAT category and rate, each with its tax amount rounded to two decimals.
2. Sum those `cbc:TaxAmount` values with decimal arithmetic and round to two decimals.
3. Write the result to `cbc:TaxAmount` directly under the same `cac:TaxTotal`.
4. Recalculate the total with VAT from the corrected VAT total, then the amount due. `BR-CO-15` and `BR-CO-16` check those.

The recorded example has a standard-rated breakdown and a zero-rated one.

```text
Breakdown tax amounts: 11.70 + 0.00 = 11.70
VAT total sent (BT-110): 11.80, so BR-CO-14 fails
Total with VAT sent: 80.20, which is 68.50 + 11.70
Against the 11.80 that was sent, BR-CO-15 expects 68.50 + 11.80 = 80.30, so it fails too
```

## 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 VAT total says 11.80, the breakdowns add up to 11.70

```xml
<cac:TaxTotal>
  <cbc:TaxAmount currencyID="GBP">11.80</cbc:TaxAmount>
  <cac:TaxSubtotal>
    <cbc:TaxableAmount currencyID="GBP">58.50</cbc:TaxableAmount>
    <cbc:TaxAmount currencyID="GBP">11.70</cbc:TaxAmount>
    <cac:TaxCategory>
      <cbc:ID>S</cbc:ID>
      <cbc:Percent>20</cbc:Percent>
      <!-- tax scheme omitted from this fragment -->
    </cac:TaxCategory>
  </cac:TaxSubtotal>
  <cac:TaxSubtotal>
    <cbc:TaxableAmount currencyID="GBP">10.00</cbc:TaxableAmount>
    <cbc:TaxAmount currencyID="GBP">0.00</cbc:TaxAmount>
    <cac:TaxCategory>
      <cbc:ID>Z</cbc:ID>
      <cbc:Percent>0</cbc:Percent>
      <!-- tax scheme omitted from this fragment -->
    </cac:TaxCategory>
  </cac:TaxSubtotal>
</cac:TaxTotal>
```

Fragment of the corrected invoice: the VAT total is the sum of the two breakdowns

```xml
<cac:TaxTotal>
  <cbc:TaxAmount currencyID="GBP">11.70</cbc:TaxAmount>
  <!-- both VAT breakdowns unchanged and omitted from this fragment -->
</cac:TaxTotal>
```

Only the `cbc:TaxAmount` directly under `cac:TaxTotal` differs: 11.80 in the failing document, 11.70 in the corrected one. The failing document also reports `BR-CO-15`, because the total with VAT of 80.20 equals 68.50 plus 11.70, not 68.50 plus the 11.80 that was sent. Correcting the VAT total clears both.

### What the validator reported

- The failing invoice reports **BR-CO-14** and [BR-CO-15](https://ironfang.uk/docs/finance/rules/BR-CO-15.md). The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/BR-CO-14-invalid.xml)
  - [Download the corrected XML](https://ironfang.uk/finance/rule-examples/invoice-rich.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` alike; a credit note with the same mistake reports the same two findings.
- Raising the total with VAT and the amount due to fit a wrong VAT total does not help. With all three moved to match 11.80, the document still reports `BR-CO-14`, now on its own.
- A document with no `cac:TaxSubtotal` at all is not caught here, because the rule skips it. `BR-CO-18` reports the missing breakdown instead.

## Related rules

- [BR-CO-15 adds this VAT total to the total without VAT to check the total with VAT](https://ironfang.uk/docs/finance/rules/BR-CO-15.md)
- [BR-CO-17 checks each breakdown tax amount against its taxable amount and rate](https://ironfang.uk/docs/finance/rules/BR-CO-17.md)
- [BR-CO-18 requires at least one VAT breakdown to be present](https://ironfang.uk/docs/finance/rules/BR-CO-18.md)
- [BR-S-09 checks the tax amount of a standard-rated breakdown](https://ironfang.uk/docs/finance/rules/BR-S-09.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-20.

[The official definition of BR-CO-14](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/BR-CO-14/) 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-CO-14)
- [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
