BR-KSA-27 Warning — the invoice is accepted

QR code (KSA-14) missing from a simplified document, or not in the expected form

The rule runs on simplified documents only, and looks for a document reference with the ID QR holding a non-empty value of type text/plain. It does not read the fields inside the code: those are checked in a separate stage, so a Phase 1 code passes it. It is a warning.

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

The document must contain a QR code (KSA-14), and this code must be base64Binary.

What does this mean?

Simplified documents only: the test is wrapped in a check that looks in the document for a transaction type code starting with 02 followed by five digits — the simplified invoice and its notes. A tax invoice gets its QR code from the Authority at clearance, together with its stamp, and the taxpayer simply displays the code the Authority returns, as its detailed guidelines put it.

The test has four parts, all required: a cac:AdditionalDocumentReference block whose cbc:ID is exactly QR — two capitals with no space around them, because two parts of the test compare the ID as it stands, untrimmed; inside it a cac:Attachment and then a cbc:EmbeddedDocumentBinaryObject; a value that is not empty; and a mimeCode attribute equal to text/plain. Missing any of them brings this code.

What it does not check, although the message mentions it: that the value is valid Base64. The XML schema does that before the rules run: the element's type in UBL is base64Binary, so a value that is not Base64 fails there, as a schema error, not here. Length has its own rule: BR-CL-KSA-14 refuses anything over 1,000 characters or under one, and it is an error.

Nor does it check the fields inside the code. The validator in the Authority's SDK decodes the TLV in a stage separate from these rules and compares the tags with the document: seller name, VAT number, timestamp, total, VAT, hash, signature and public key, and on a simplified document the certificate signature in tag 9. So a Phase 1 code with its five tags passes this rule and fails that stage. The guidelines require a nine-tag code on a simplified document, TLV encoded and then Base64.

It is a warning: the document is accepted, with the warning attached. But the QR code is what the buyer and the Authority's app read to verify the invoice, and a simplified document with no code in its file is a document nobody can verify by scanning.

Why does it happen?

Ordered from the most common to the least — your cause is most likely the first or the second.

  • The code drawn on the printed receipt or the PDF, and never written into the XML.
  • The ID spelled another way: qr, QRCode or QR_CODE, or QR with a space or a line break around it from a pretty-printed template.
  • The image of the code instead of its text: a PNG file in Base64 with mimeCode="image/png" — it fails here on the type, and usually in BR-CL-KSA-14 too, because an image is far longer than 1,000 characters.
  • Confusing the encoding with the media type: mimeCode="base64" instead of text/plain, which brings BR-KSA-CL-03 with it, because base64 is not a type on the accepted IANA list.
  • An empty element left as a placeholder: the XML is built and sent before the QR step runs, or that step fails silently — and BR-CL-KSA-14 comes with it, because the length is zero.
  • The value written directly under the document reference, without the cac:Attachment wrapper.

How to fix it

4 steps, then send the invoice again.

  1. 1
    Build the code after signing

    Tag 6 is the invoice hash and tag 7 its signature, so the code cannot be built before the stamp. The order: build the document, compute the hash, sign, then build the nine tags and encode them as TLV — tag, then length in bytes, then value — then Base64, then write it into the document. This does not spoil the hash: the QR block is removed before the hash is computed, which is step two of the steps in BR-KSA-26.

  2. 2
    Write the block in its shape and in its place

    <cac:AdditionalDocumentReference><cbc:ID>QR</cbc:ID><cac:Attachment><cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain">AQ...</cbc:EmbeddedDocumentBinaryObject></cac:Attachment></cac:AdditionalDocumentReference> — after the ICV and PIH references and before the cac:Signature block, as in the Authority's SDK samples. The stamp and its block are covered in BR-KSA-60.

  3. 3
    The text in the file, the picture on paper

    The value in the XML is the Base64 string itself — not an image of the code, not a link to one — and it is between one and 1,000 characters long. The picture is drawn from the string when printing or on the PDF, and it never goes into the file.

  4. 4
    Check the code before you report

    Paste the string into the QR code reader: it decodes the TLV, lists the fields and tells you whether the code is Phase 1 or Phase 2. Five fields only means a Phase 1 code: it passes this rule and fails the content check.

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. The QR code in ZATCA Tools is built in the signing step itself, for every document: eight tags from the invoice data, its hash, its signature and the certificate key, plus a ninth on a simplified document and its notes — the certificate signature — then TLV and Base64 encoded and written in a block with the ID QR and the type text/plain. No document is sent before that step completes. A tax invoice gets its code the same way before clearance; the Authority then applies its own stamp and code, and the stamped file it returns becomes the document of record once its stamp verifies and its hash matches what was signed.

Related codes

Frequently asked questions

My tax invoice has no QR code of mine. Does it fail here? +
No. The test runs only on simplified documents. A tax invoice gets its code from the Authority at clearance, and the guidelines say the taxpayer displays the code the Authority returns. The difference between the two documents is in standard vs simplified tax invoice.
My code is a Phase 1 code with five tags. Is that enough? +
It is enough for this rule alone, because the rule checks that the block is there and in shape, not what is in it. But a simplified document in Phase 2 carries a nine-tag code, and the tags are checked in another stage of the validator that compares them with the document. You can see what your code holds with the QR code reader.
The message says base64Binary, so why did my unencoded code not fail here? +
Because Base64 validity is checked by the XML schema before the rules, and the element is of type base64Binary in UBL, so an invalid value fails there as a schema error. This rule, as it runs, checks that the block exists, its ID, that the value is not empty and that its type is text/plain.
Do I put the image of the code in the file? +
No. The file carries the string; the image is for the printed copy. A PNG in the element fails here on the type image/png, and usually in BR-CL-KSA-14 on the length.
Is the QR code part of the invoice hash? +
No. The QR block is removed before the hash is computed, together with the stamp block and the cac:Signature block — the steps are in BR-KSA-26. That is why the code is built after signing and does not change what was signed.
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