Only one tax total (BG-22) with tax subtotals must be provided.Refer to Calculation of VAT.
What does this mean?
This is the sibling of BR-KSA-EN16931-09, counting the other kind of block. With the tax accounting currency declared, the document carries two cac:TaxTotal blocks: a detailed one, holding the total VAT and a cac:TaxSubtotal for each tax category in the invoice currency, and a bare one, holding the VAT total in SAR and nothing else. That rule wants exactly one bare block; this one wants exactly one detailed block.
Every category goes inside that single block. The message points to the Calculation of VAT, a section of ZATCA's XML Implementation Standard, which asks for one VAT breakdown per distinct combination of category code and rate; its worked example sets a standard-rated subtotal and an exempt subtotal side by side in one cac:TaxTotal. A second category is a second cac:TaxSubtotal, never a second tax total.
The block in question sits directly under the invoice. The same standard lists what this rule uses as /ubl:Invoice/cac:TaxTotal/cac:TaxSubtotal, and ZATCA's Data Dictionary ties the rule to the invoice total VAT amount (BT-110) and to the total in accounting currency (BT-111). The cac:TaxTotal inside each invoice line is a different element, carrying that line's VAT (KSA-11) and its amount with VAT (KSA-12).
Its severity in the schematron is a warning: the document is accepted and the warning is recorded with it.
Why does it happen?
Ordered from the most common to the least — your cause is most likely the first or the second.
-
One
cac:TaxTotalwritten per VAT category: a basket of standard-rated and zero-rated lines leaves as two blocks with one subtotal each, instead of one block with two. - The breakdown copied into the SAR block as well, for instance while adding that block to fix BR-KSA-EN16931-09. Both blocks then carry subtotals and no bare block is left, so the two codes arrive together.
-
One rate written two ways,
15on one line and15.00on another, grouped as two categories and given a block each. The standard is explicit that trailing zeros must not split a breakdown. -
A document-level tax block written inside the loop over the lines, so the invoice gains a detailed
cac:TaxTotalper line at its own level instead of one inside eachcac:InvoiceLine. - A credit or debit note assembled by appending the original invoice's tax block to the note's own.
How to fix it
4 steps, then send the invoice again.
-
1
Group the lines, then write one detailed block
Group by category code and rate, with
15and15.00as one group, and write a singlecac:TaxTotalholding the total VAT and onecac:TaxSubtotalper group, each with its taxable amount, its tax amount and itscac:TaxCategory. The category letters are covered in BR-KSA-18. -
2
Keep the SAR block bare
The other
cac:TaxTotalholdscbc:TaxAmountwithcurrencyID="SAR"and nocac:TaxSubtotal. If a copy of the breakdown went in there too, take it out: being empty of subtotals is what that block is for, and its own rule is BR-KSA-EN16931-09. -
3
Derive the total from the subtotals
The XML Implementation Standard defines the invoice total VAT amount as the sum of the category tax amounts. Add up the subtotals you have just written instead of computing the total along a separate path, and the detailed block agrees with itself by construction.
-
4
Check the notes path on its own
If credit and debit notes are built by different code from invoices, test that code separately: a note that appends the invoice's tax block to its own fails here while every invoice is clean. The mechanics of notes are in credit and debit notes.
This code does not block acceptance, so the invoice you have is compliant. Correct the data so the warnings disappear from future invoices.
Does ZATCA Tools prevent it?
Yes, by construction. The payload builder puts every VAT subtotal of a document, one per tax category, inside a single tax total, and the XML library writes that as exactly one cac:TaxTotal with subtotals beside one bare cac:TaxTotal carrying the same amount in SAR. We read the output back rather than trusting the intent: a document that mixes standard-rated and zero-rated lines leaves with one detailed block holding two subtotals, and one bare block. No screen, API field or store integration accepts a tax total, a subtotal or a tax amount from outside; both blocks are computed from the lines.
Related codes
Frequently asked questions
Was my invoice rejected because of this code? +
My invoice mixes standard-rated and zero-rated items. Are two tax totals not right? +
cac:TaxSubtotal inside the one detailed block, which is exactly how the worked example in the XML Implementation Standard is built. The second cac:TaxTotal your document does carry is the bare one in SAR.The lines in my file each carry a TaxTotal too. Do they count? +
/ubl:Invoice/cac:TaxTotal/cac:TaxSubtotal. A line's own cac:TaxTotal is a different element that belongs inside cac:InvoiceLine, and on a prepayment line it even holds a subtotal of its own by design (KSA-31 and KSA-32). We read each rule's message and severity, not its test, so we cannot show you the check itself; a file whose invoice level holds exactly one detailed block is the shape the message describes.I added the SAR block for BR-KSA-EN16931-09 and now I see this one. What happened? +
cac:TaxSubtotal elements from the copy, and the file holds one block of each kind.ZATCA Tools builds the signature, the PIH, the counter and the encoding for you, and validates your data before it is sent. Start free, with no credit card.
Start for free