BR-CO – Conditions and calculations
BR-CO-17: VAT amount (BT-117) does not match taxable amount and rate
ErrorEN 16931 business rule (CEN)
The rule's own wording
[BR-CO-17]-VAT category tax amount (BT-117) = VAT category taxable amount (BT-116) x (VAT category rate (BT-119) / 100), rounded to two decimals.Source: CEN EN 16931, version 1.3.16
Meaning of the rule
In a breakdown of your invoice the stated tax amount does not match the result of the taxable amount times the rate. The norm recalculates per VAT category: base amount times rate divided by one hundred, rounded to two decimals. One cent of difference is enough for a rejection, because the recipient books the tax amount exactly as it stands in the invoice. The error usually arises when the tax is rounded per line and then summed.
What usually goes wrong
- The tax was rounded per line and added up instead of being calculated on the category's total.
- Taxable amount or tax amount were not recalculated after a change.
- The rate in the breakdown differs from the rate of the lines.
The fix in the XML
Calculate per breakdown the tax amount from the category's taxable amount and the rate, rounded to two decimals, and enter it in cbc:TaxAmount. Line amounts serve only as a check, not as the sum.
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">937.40</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">178.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19</cbc:Percent>
<cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal><cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="EUR">937.40</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="EUR">178.11</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>19</cbc:Percent>
<cac:TaxScheme><cbc:ID>VAT</cbc:ID></cac:TaxScheme>
</cac:TaxCategory>
</cac:TaxSubtotal>Questions and answers
Why may I not calculate the tax per line and sum it up?
Because the norm calculates the tax per category from the sum of the base amounts. Amounts rounded per line often differ by one cent in the sum.
Which rounding is meant?
Commercial rounding to two decimals: from 0.005 upwards. Truncating or banker's rounding leads to differences and thus to BR-CO-17.
EN 16931 fields
- BT-117
- BT-116
- BT-119
- BG-23
See also
- BR-AF-09
- BR-AG-09
- BR-S-09
Check your invoice
The EN 16931 validator reports this rule with the line number and location – right in your browser, without upload.
The rule in detail
- UBL · Context (XPath)
cac:TaxTotal/cac:TaxSubtotal- UBL · Schematron test
(round(cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/xs:decimal(cbc:Percent)) = 0 and (round(xs:decimal(cbc:TaxAmount)) = 0)) or (round(cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/xs:decimal(cbc:Percent)) != 0 and ((abs(xs:decimal(cbc:TaxAmount)) - 1 < round(abs(xs:decimal(cbc:TaxableAmount)) * (cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/xs:decimal(cbc:Percent) div 100) * 10 * 10) div 100 ) and (abs(xs:decimal(cbc:TaxAmount)) + 1 > round(abs(xs:decimal(cbc:TaxableAmount)) * (cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/xs:decimal(cbc:Percent) div 100) * 10 * 10) div 100 ))) or (not(exists(cac:TaxCategory[cac:TaxScheme/normalize-space(upper-case(cbc:ID))='VAT']/xs:decimal(cbc:Percent))) and (round(xs:decimal(cbc:TaxAmount)) = 0))- CII · Context (XPath)
//ram:ApplicableHeaderTradeSettlement/ram:ApplicableTradeTax- CII · Schematron test
(round(.[normalize-space(upper-case(ram:TypeCode)) = 'VAT']/xs:decimal(ram:RateApplicablePercent)) = 0 and (round(xs:decimal(ram:CalculatedAmount)) = 0)) or (round(.[normalize-space(upper-case(ram:TypeCode)) = 'VAT']/xs:decimal(ram:RateApplicablePercent)) != 0 and ((abs(xs:decimal(ram:CalculatedAmount)) - 1 <= round(abs(xs:decimal(ram:BasisAmount)) * (.[normalize-space(upper-case(ram:TypeCode)) = 'VAT']/xs:decimal(ram:RateApplicablePercent) div 100) * 10 * 10) div 100 ) and (abs(xs:decimal(ram:CalculatedAmount)) + 1 >= round(abs(xs:decimal(ram:BasisAmount)) * (.[normalize-space(upper-case(ram:TypeCode)) = 'VAT']/xs:decimal(ram:RateApplicablePercent) div 100) * 10 * 10) div 100 ))) or (not(exists(.[normalize-space(upper-case(ram:TypeCode))='VAT']/xs:decimal(ram:RateApplicablePercent))) and (round(xs:decimal(ram:CalculatedAmount)) = 0))
Explanation written on 14 September 2026