The invoice must contain a unique identifier ("UUID") (KSA-1) given by the unit that issued the document (unique message identifier for interchange process). This value must contain only letters, digits, and dashes.
What does this mean?
Every document carries two identifiers that are easy to confuse. The invoice number (BT-1) is the readable sequence you print on the page and quote to a customer. The UUID (KSA-1) is a machine identifier for the same document inside the exchange with the Authority: nobody reads it, and it exists so that one document can be pointed at without ambiguity.
The rule checks two things at once. The field must be present, and its value may hold letters, digits and dashes only. The canonical UUID form satisfies that: 36 characters as 8-4-4-4-12 hexadecimal digits separated by dashes, for example f6e1c7b4-3a0d-4a3e-9f2b-1d8c5e4a7b90.
One document, one UUID. An invoice, a credit note and a debit note are three documents and take three values, and a document keeps the value it was issued with.
Why does it happen?
Ordered from the most common to the least — your cause is most likely the first or the second.
- XML built from a sample file where the UUID of the sample was never replaced — every document then goes out carrying the same value.
- Generating the UUID once, at start-up or in a configuration file, and reusing the variable for the whole run.
-
Writing the invoice number into the field:
INV-2026/0042fails on the slash, andINV_42fails on the underscore, which is not a dash. -
Wrapping the value: a
urn:uuid:prefix, or the braces thatGuid.ToString("B")produces in .NET — the colon and the braces are outside the permitted set. -
A placeholder left over from testing, such as
00000000-0000-0000-0000-000000000000: it passes the character condition and identifies nothing, which makes it the hardest of these to notice.
How to fix it
3 steps, then send the invoice again.
-
1
Generate one per document, at the moment you create it
Generate a version 4 UUID when the document row is created, store it on the row, and send the stored value. Generating at send time instead means every retry gives the same document a different identifier.
-
2
Emit it bare
36 lowercase characters with dashes: no
urn:uuid:prefix, no braces, no surrounding whitespace. TheNformat in .NET (32 characters, no dashes) passes the character condition but is not the canonical form;Dis the one you want. -
3
Keep the invoice number in its own field
BT-1 is where
INV-2026-0042belongs, and the invoice counter (KSA-16) is a third field again that takes digits only — see BR-KSA-34. Three fields, three jobs, and no value shared between them.
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, and there is no way to reach it from our side: ZATCA Tools generates a version 4 UUID when the document row is created — invoice, credit note and debit note alike — stores it on the row and sends the stored value. No screen and no API field accepts a UUID from outside, so it can neither be reused nor malformed. This page is here for anyone building the integration themselves, or using another solution that generates the XML.
Related codes
Frequently asked questions
Is the UUID the same as the invoice number? +
Can I use my own sequential number instead of a UUID? +
My invoice was rejected. Do I resend with the same UUID or a new one? +
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