BR-KSA-03 Rejects the invoice

Invoice UUID missing or invalid

KSA-1 is a machine identifier for the document, not the invoice number a customer reads. It is generated fresh for every document, and the rule puts a second condition on which characters it may hold.

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

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/0042 fails on the slash, and INV_42 fails on the underscore, which is not a dash.
  • Wrapping the value: a urn:uuid: prefix, or the braces that Guid.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. 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. 2
    Emit it bare

    36 lowercase characters with dashes: no urn:uuid: prefix, no braces, no surrounding whitespace. The N format in .NET (32 characters, no dashes) passes the character condition but is not the canonical form; D is the one you want.

  3. 3
    Keep the invoice number in its own field

    BT-1 is where INV-2026-0042 belongs, 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? +
No, and one does not stand in for the other. BT-1 is the number a human reads and that your books are organised by; KSA-1 is a machine identifier used in the exchange with the Authority. Both are on the document, and putting one where the other belongs is the most common road to this code.
Can I use my own sequential number instead of a UUID? +
The character condition would not stop you, since digits are permitted — but the field is specified as a UUID, and a sequence is precisely what a UUID exists to avoid: two units issuing at the same moment produce the same next number, while two randomly generated identifiers do not collide. Use the UUID generator your language already ships.
My invoice was rejected. Do I resend with the same UUID or a new one? +
A rejected document was never recorded at the Authority, so nothing there is holding the old value and either choice is accepted. Keeping the value the document was created with is the cleaner one: the identifier then stays the same thing across your logs and your retries. How to read the rejection response is covered in ZATCA error codes explained.
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. Completely free for now, and no credit card.

Start for free

← All ZATCA error codes