The invoice counter value (KSA-16) contains only digits.
What does this mean?
Two rules sit on the same field and are easy to mix up. BR-KSA-33 says the counter must exist; this one says what it may contain: digits, and nothing besides. A counter of INV-001 exists, so 33 passes it and 34 rejects it.
The counter is an integer belonging to the issuing unit, going up by one per document, never reset and never repeated. The number your customer reads (BT-1) is a separate field that may carry letters, a year, a branch code, whatever you like. The confusion between the two is the whole of this code.
What the word digits excludes is wider than it looks: letters, dashes, slashes, spaces, a decimal point, a thousands separator, a leading hash — and Arabic-Indic digits. A number formatted in an Arabic locale can come out as ١٠٢٤, which is a number to your eye and not to the validator.
It rejects, and there is something useful in that when you come to repair it: since every counter carrying a prefix was refused, the sequence recorded at the Authority is whatever numeric value was last accepted, and nothing before it needs fixing.
Why does it happen?
Ordered from the most common to the least — your cause is most likely the first or the second.
-
The invoice number used as the counter:
INV-001,2026/14,A-1024. -
A prefix per document type or per branch —
CN-15for a credit note,RYD-88for a branch — usually added so that a human can tell the sequences apart. -
The year glued onto the sequence:
2026-1024is rejected on the dash, and20261024passes this rule while quietly making the counter something other than a count. -
A value that went through a number formatter on the way out:
1,024from a thousands separator, or Arabic-Indic digits from a locale-aware call. - Whitespace or a leading apostrophe carried over from a spreadsheet cell — invisible on screen and part of the value.
How to fix it
3 steps, then send the invoice again.
-
1
Store an integer, format it never
Keep the counter in an integer column, increment it inside the same transaction that issues the document, and cast it to a string at the last moment with nothing that formats numbers for humans anywhere in the path.
-
2
Give the readable number its own field
BT-1 is where
INV-2026-0042belongs, and the document can print both. The UUID (KSA-1) is a third identifier again — see BR-KSA-03. Relate the three, never merge them. -
3
Pick the sequence up from the last accepted value
Everything the Authority accepted carried a numeric counter, because this rule rejects anything else. Take the highest counter among your accepted documents, continue from the next integer, and leave the gap where the rejected attempts were: a gap is not a violation, a repeat is.
Once corrected, send the invoice again. A rejected invoice was never recorded with the Authority, so it needs no credit note — send the corrected invoice itself.
Does ZATCA Tools prevent it?
Yes. The counter is an integer column that ZATCA Tools increments under a lock at the moment of issue — per branch device where the establishment has branch devices, per establishment otherwise — and it goes into the XML as an integer. There is no field anywhere in the product where a counter can be typed, so no prefix can get into one.
Related codes
Frequently asked questions
Can the counter have leading zeros? +
Do I have to change my invoice numbers? +
My system used the invoice number as the counter and every send is rejected. How do I separate them without breaking the sequence? +
ZATCA Tools builds the signature, the PIH, the counter and the encoding for you, and validates your data before it is sent. Completely free for now, and no credit card.
Start for free