BR-KSA-EN16931-08 Warning — the invoice is accepted

More than one tax total carrying the VAT breakdown

A document carries one tax total with the VAT breakdown inside it, and only one. A mixed basket split into a tax total per rate, or the breakdown copied into the SAR block as well, triggers this code. It is a warning, so the invoice is accepted.

The message text as the Authority sends it in English, unedited

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:TaxTotal written 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, 15 on one line and 15.00 on 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:TaxTotal per line at its own level instead of one inside each cac: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. 1
    Group the lines, then write one detailed block

    Group by category code and rate, with 15 and 15.00 as one group, and write a single cac:TaxTotal holding the total VAT and one cac:TaxSubtotal per group, each with its taxable amount, its tax amount and its cac:TaxCategory. The category letters are covered in BR-KSA-18.

  2. 2
    Keep the SAR block bare

    The other cac:TaxTotal holds cbc:TaxAmount with currencyID="SAR" and no cac: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. 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. 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? +
Its severity in the schematron is a warning, and a document carrying it is accepted with the warning recorded. If your invoice really was rejected, the reason is elsewhere: the Authority's response separates errorMessages, which reject the document, from warningMessages, which are only recorded.
My invoice mixes standard-rated and zero-rated items. Are two tax totals not right? +
Two subtotals, not two tax totals. Each distinct category and rate gets its own 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? +
The standard lists this rule's usage as the tax total directly under the invoice, /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? +
If the new block was made by copying the detailed one, it carries the subtotals too: that leaves two detailed blocks and no bare one, which breaks both counts at once. Remove the cac:TaxSubtotal elements from the copy, and the file holds one block of each kind.
You fixed this one — now avoid the next

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

← All ZATCA error codes