# BR-DEC-20: Write each VAT breakdown tax amount with no more than two decimals

The `cbc:TaxAmount` of a `cac:TaxSubtotal` has more than two digits after the decimal point. Round the VAT category tax amount to two decimals.

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

## The short answer

`BR-DEC-20` fails when the `cbc:TaxAmount` inside a `cac:TaxSubtotal` has more than two digits after the decimal point. Round the tax amount of that VAT breakdown to two decimals and write it with no more.

The finding points at the `cac:TaxSubtotal`, so with several VAT categories check the one named in the location. `UBL-DT-01` is reported on its `cbc:TaxAmount` at the same time.

## What the rule checks

The rule runs on every `cac:TaxSubtotal` inside a `cac:TaxTotal` and counts the characters after the decimal point in its `cbc:TaxAmount`. Two or fewer pass.

Every breakdown is held to the limit, whatever its category or rate. When tried, a zero-rated breakdown with a tax amount of `0.000` failed in the same way as the standard-rated one.

The taxable amount of the same breakdown belongs to `BR-DEC-19`, and the VAT total above the breakdowns is left to `UBL-DT-01` alone. When tried with both the standard-rated breakdown and the VAT total written as `11.700`, this rule was reported once and `UBL-DT-01` twice.

Only the written form is tested. When tried, `11.704` reported this rule and `UBL-DT-01` and nothing else, because the VAT total check rounds the sum of the breakdowns and the rate checks allow a margin; `11.705` rounds up to 11.71 and also brought `BR-CO-14`.

| Term | Meaning | UBL element |
|---|---|---|
| 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 per category is calculated as taxable amount times rate and written unrounded, or rounded but written by a formatter set to three decimals.
- The breakdown is built by adding line VAT amounts that were kept at three or four decimals.
- A tax engine returns amounts at its internal precision and the mapping passes them straight through.

## How to fix it

1. Calculate each breakdown tax amount from its taxable amount and rate, and round it to two decimals once.
2. Write the rounded value, with at most two decimals and no whitespace, to `cbc:TaxAmount` inside that `cac:TaxSubtotal`.
3. Add the rounded breakdown amounts for the VAT total, so `BR-CO-14` agrees, and write that total with two decimals as well.

## 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 standard-rated breakdown gives its tax as 11.700

```xml
<cac:TaxTotal>
  <cbc:TaxAmount currencyID="GBP">11.70</cbc:TaxAmount>
  <cac:TaxSubtotal>
    <cbc:TaxableAmount currencyID="GBP">58.50</cbc:TaxableAmount>
    <cbc:TaxAmount currencyID="GBP">11.700</cbc:TaxAmount>
    <cac:TaxCategory>
      <cbc:ID>S</cbc:ID>
      <cbc:Percent>20</cbc:Percent>
      <!-- tax scheme omitted from this fragment -->
    </cac:TaxCategory>
  </cac:TaxSubtotal>
  <!-- zero-rated breakdown omitted from this fragment -->
</cac:TaxTotal>
```

Fragment of the corrected invoice: the same tax amount written as 11.70

```xml
<cac:TaxTotal>
  <cbc:TaxAmount currencyID="GBP">11.70</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>
  <!-- zero-rated breakdown omitted from this fragment -->
</cac:TaxTotal>
```

In the failing invoice the standard-rated breakdown states its tax as `11.700`; the corrected invoice states `11.70`, and the VAT total above it reads 11.70 in both. Since the value is unchanged, `BR-CO-14` and the other VAT checks still pass. Two findings are reported: `BR-DEC-20` at the first `cac:TaxSubtotal`, and `UBL-DT-01` at its `cbc:TaxAmount`. The latter enforces two decimals on every element named as an amount, with only item prices and price-level allowance amounts left out, so a breakdown tax amount cannot fail one without the other.

### What the validator reported

- The failing invoice reports **BR-DEC-20** and [UBL-DT-01](https://ironfang.uk/docs/finance/rules/UBL-DT-01.md). The corrected document passes every layer with no findings.
  - [Download the failing XML](https://ironfang.uk/finance/rule-examples/BR-DEC-20-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`. When tried, a credit note with `11.700` in the same breakdown reported the same two rules.
- The rule reads the text only, so it neither knows nor cares which currency the amount is in.
- For the VAT total itself there is no working counterpart to this rule in the pinned release, which is why padding that figure reports `UBL-DT-01` on its own.

## Related rules

- [UBL-DT-01 reports the breakdown tax amount alongside this rule, and alone covers the VAT total above it](https://ironfang.uk/docs/finance/rules/UBL-DT-01.md)
- [BR-CO-14 adds the breakdown tax amounts to check the VAT total](https://ironfang.uk/docs/finance/rules/BR-CO-14.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)

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