BR-DEC-20VAT category tax amount is written with more than two decimal places

Mutabiq checks Saudi ZATCA Phase 2 e-invoice XML before you submit it: pre-validation against published ZATCA requirements, not an approval by the authority. This page explains one rule, BR-DEC-20.

Validate 5 invoices free

Five checks a month on the Free plan. The file is checked in memory and is never stored.

The message ZATCA prints

[BR-DEC-20]-The allowed maximum number of decimals for the VAT category tax amount (BT-117) is 2.

What Mutabiq reports

One entry for each way this rule can be reported.

Reported as
What kind of value was found — empty, not_15_digits and the like — never the value itself.

VAT category tax amount is written with more than two decimal places

Reported asmore_than_two_decimalsmore than two decimal places

What is wrong

A cbc:TaxAmount in a VAT breakdown - BT-117, the VAT due for one category - carries more than two characters after its first full stop, and ZATCA flags it under EN 16931 rule BR-DEC-20 as a warning, which does not by itself reject the document. This is not the same element that BR-DEC-13 and BR-DEC-15 read, although the name is identical: this one sits inside a cac:TaxSubtotal, the per-category breakdown, while theirs is the direct child of the cac:TaxTotal and states the whole invoice's VAT. The rule counts the characters after the first full stop in the element's text rather than judging the value, so a third digit fails even when it is a nought, and a value written with no full stop at all passes however large it is. An absent or empty element passes as well. Its sibling in the same breakdown, the category taxable amount BT-116, is checked by BR-DEC-19, so the two are commonly reported together.

What to check in your ERP

This figure is a rate applied to a taxable base, and fifteen per cent of an ordinary base is very often not a two-decimal number, so the rounding has to be deliberate. Round each category's VAT amount to two decimals, and then build the header total from those rounded figures rather than computing the header independently, because BR-CO-14 requires the invoice total VAT amount to equal the sum of these breakdown amounts. Check that a zero-rated or exempt category is writing an exact nought here rather than a computed value that happens to be very small, and check whether the taxable base beside it is itself carrying extra precision, because a percentage of a base that already has three decimals cannot come out at two. Where the breakdown comes from a tax engine, confirm that the engine rounds per category and per invoice rather than per line and then aggregating unrounded results.

The clause that runs

Quoted from the validation-rule stylesheet ZATCA publishes, at the file and line named below. The executed guard is what the check runs; the reported test is what it prints when it fails, and the two are not always the same.

Executed guard

not(string-length(substring-after(cbc:TaxAmount,'.'))<=2)

Reported test

string-length(substring-after(cbc:TaxAmount,'.'))<=2
Evaluated against
/ubl:Invoice/cac:TaxTotal/cac:TaxSubtotal
Source
vendor/zatca/schematron/CEN-EN16931-UBL.xsl:1303

As shipped in ZATCA SDK 3.4.8: the copy quoted here is, byte for byte, the file that release ships. The date in the file name is the name ZATCA gives the file; the rules in it are those of SDK 3.4.8.

A worked example

A synthetic document from the measured test corpus that trips this rule, shown where it differs from one that passed. Mutabiq's report names the class of the value, never the value itself.

Document
bad-94-category-tax-amount-decimals.xml
Mutabiq's verdict
Passed
Reported as
more_than_two_decimalsmore than two decimal places

Download this example (.xml)Check it in Mutabiq

This page's example, checked by the same rules your own upload goes through. No upload and no sign-in.

Rules evaluated against the same part of the document. One wrong value often reports several of them at once.

Check an invoice

Check your own invoice

© 2026 Hayatiq AI Solutions F.Z.E. All rights reserved.