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-KSA-33.
Five checks a month on the Free plan. The file is checked in memory and is never stored.
The message ZATCA prints
[BR-KSA-33]-Each invoice must have an invoice counter value (KSA-16).
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.
Invoice counter value is missing
Reported asicv_reference_missingthe invoice counter reference is missing
What is wrong
The document carries no cac:AdditionalDocumentReference whose cbc:ID is ICV, so it states no invoice counter value (KSA-16). ZATCA requires every invoice to carry one under BR-KSA-33. The counter is the sequential number of this document in the issuing device or system's own unbroken series, and it is what lets the authority tell whether an invoice in the chain is missing.
What to check in your ERP
The counter is written as its own document reference block: a cac:AdditionalDocumentReference whose cbc:ID is the literal text ICV and whose cbc:UUID holds the counter. It is not the invoice number (BT-1) and it does not reset per customer, per branch or per year - it increments by one for every document the device or system issues, credit and debit notes included. Check that your e-invoicing module maintains that counter and writes the block; a module that was configured for Phase 1 often does not.
Invoice counter reference carries no value
Reported asno_reference_uuidthe reference carries no value
What is wrong
The document has a cac:AdditionalDocumentReference identified as ICV, but no document reference at the root of the invoice carries a non-empty cbc:UUID, so the counter block is there and the counter itself is not. ZATCA fails this under BR-KSA-33, which requires both the reference and a value.
What to check in your ERP
The counter goes in the cbc:UUID of the ICV reference block, and an empty element is treated exactly as a missing one. This usually means the block is written from a template that emits the ICV label unconditionally while the counter itself comes from a field that was never populated - so check the value the mapping reads, not only that the block is produced. The counter increments by one for every document the issuing device or system emits.
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((cac:AdditionalDocumentReference[normalize-space(cbc:ID) = 'ICV'] and (cac:AdditionalDocumentReference/cbc:UUID) != ''))
Reported test
(cac:AdditionalDocumentReference[normalize-space(cbc:ID) = 'ICV'] and (cac:AdditionalDocumentReference/cbc:UUID) != '')
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.
Where it differs from a document that passed
− This example
+ A document that passed
<cbc:TaxCurrencyCode>SAR</cbc:TaxCurrencyCode><cac:AdditionalDocumentReference>+A document that passed: <cbc:ID>ICV</cbc:ID>+A document that passed: <cbc:UUID>1</cbc:UUID>+A document that passed: </cac:AdditionalDocumentReference>+A document that passed: <cac:AdditionalDocumentReference> <cbc:ID>PIH</cbc:ID> <cac:Attachment>
Document
bad-05-missing-icv.xml
Mutabiq's verdict
Not passed
Reported as
icv_reference_missingthe invoice counter reference is missing