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.
Simplified invoice carries no QR code reference
Reported asreference_missingthe reference is missing
What is wrong
The document carries no cac:AdditionalDocumentReference whose cbc:ID is QR, so it has no QR code on it at all. SDK 3.4.8 flags a simplified invoice in that state under BR-KSA-27, which requires the document to carry a QR code (KSA-14), as a warning, not a rejection: the finding is reported without failing the document by itself. The id is compared after whitespace is normalised, so spacing around QR is not what is wrong; but it is compared exactly otherwise, so a reference labelled qr in lower case, or QRCODE, is not the reference this rule looks for and reads as absent. The rule applies to simplified invoices only - a standard invoice with no QR code is not reported by it.
What to check in your ERP
The QR code travels in a document reference block of its own: a cac:AdditionalDocumentReference whose cbc:ID is the literal text QR, holding cac:Attachment/cbc:EmbeddedDocumentBinaryObject with the base64 payload inside it. The usual causes are an export template written for standard invoices and reused for simplified ones without the QR block ever being added, a QR generator that runs for the printed copy and not for the XML, and a mapping that writes the block only when the generator returns a value and skips it silently when it returns nothing. Look at the neighbouring blocks while you are there: the same element carries the invoice counter (ICV) and the previous invoice hash (PIH) under different ids, so a document that carries those and not QR usually means only the QR branch of the mapping is missing.
QR code reference carries no payload element
Reported aspayload_element_missingthe payload element is missing
What is wrong
The document has a cac:AdditionalDocumentReference whose cbc:ID is QR, but there is no cac:Attachment/cbc:EmbeddedDocumentBinaryObject inside it: the reference block is present and the element that would hold the QR code is not. ZATCA flags a simplified invoice in that state under BR-KSA-27, as a warning, which does not by itself reject the document. If the document carries more than one QR reference, any one of them carrying the payload element satisfies the check, so this is reported only when none of them does.
What to check in your ERP
Check the shape of the block your export writes: two levels inside the reference, a cac:Attachment and a cbc:EmbeddedDocumentBinaryObject inside that, with the base64 payload as the second one's text content. The usual causes are a template that writes the reference and its cbc:ID from one loop and the attachment from another that did not run, a QR value written into the reference's own text or into a description element instead of into the attachment, and a nesting level dropped so that the binary object sits directly under the reference. A payload element that is present but empty is a different defect and is reported as its own finding.
No document reference on this invoice carries a non-empty payload
Reported asall_payloads_emptyevery document reference's payload is empty
What is wrong
This is not the finding for an empty QR code, and only rule packs before 2.0.0 report it. In SDK 3.0.8 the part of BR-KSA-27 behind it was not restricted to the QR reference: ZATCA evaluated it over every cac:AdditionalDocumentReference in the document, as an XPath general comparison, so it was satisfied as soon as any one of those references carried a payload that is not the empty string, and it failed only when no additional document reference anywhere in the document carried a non-empty cac:Attachment/cbc:EmbeddedDocumentBinaryObject. A non-empty previous invoice hash (PIH) payload satisfied it on its own even when the QR payload next to it was empty. In SDK 3.4.8, which rule pack 2.0.0 reads, the same conditions read the QR reference's own payload (KSA:366-371), so an empty QR payload is reported as the QR code element being empty, as a warning, and a report produced under 2.0.0 never carries this note.
What to check in your ERP
Because the test spans the whole document, reaching it usually means the attachments are being written as empty elements throughout rather than that one generator failed. Check that the step which fills cac:Attachment/cbc:EmbeddedDocumentBinaryObject runs before the document is serialised, and that it runs for every reference block the document carries - the QR code, and on a simplified invoice the previous invoice hash. A mapping that emits the block structure unconditionally and fills it from a value that is null or an empty string produces exactly this. Fix the generator or the mapping in your e-invoicing module rather than deleting the empty blocks: deleting the QR block moves the document onto the finding for a missing QR reference instead.
QR code payload is not declared text/plain
Reported asno_text_plain_payloadno payload declared text/plain
What is wrong
ZATCA requires the QR code to be declared as text/plain, which is carried in the mimeCode attribute on cac:Attachment/cbc:EmbeddedDocumentBinaryObject inside the QR reference. In SDK 3.4.8, which rule pack 2.0.0 reads, this condition reads the payload of the QR reference itself (KSA:366-371); earlier releases looked at every document reference and were satisfied by any attachment declared text/plain, the previous invoice hash one included. The value is compared after whitespace is normalised and exactly otherwise: text/plain is what is required, and application/octet-stream, base64Binary, an empty attribute and no mimeCode attribute at all each fail. ZATCA flags the simplified invoice under BR-KSA-27 as a warning, which does not by itself reject the document.
What to check in your ERP
The attribute belongs on the element that holds the payload, not on the cac:Attachment above it: mimeCode with the value text/plain on cbc:EmbeddedDocumentBinaryObject. Do not reason the value out from what the payload contains. The payload is base64 of a byte sequence, so application/octet-stream looks the more accurate of the two and draws this note; text/plain is what the checker requires. The usual causes are a serialiser that writes the attachment through a generic binary-attachment helper carrying its own default type, an attribute read from a document-management table, and a template that omits it. Compare against a ZATCA sample simplified invoice, which carries a mimeCode of text/plain on this element.
Simplified invoice's QR code element is empty
Reported aspayload_emptythe payload is empty
What is wrong
On a simplified invoice the QR reference (the cac:AdditionalDocumentReference whose ID is QR) is present, but its cbc:EmbeddedDocumentBinaryObject holds nothing, or only spaces. BR-KSA-27 requires a QR code on a simplified invoice. ZATCA flags this as a warning, which does not by itself reject the document. BR-CL-KSA-14 reports an element with no characters at all as an error.
What to check in your ERP
Generate the QR before the XML is written and write the base64 payload into the element. An empty element usually means the export runs before the QR step, or that the step failed and the export carried on.
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) = 'QR'] and exists(cac:AdditionalDocumentReference[normalize-space(cbc:ID) = 'QR']/cac:Attachment/cbc:EmbeddedDocumentBinaryObject) and (normalize-space(cac:AdditionalDocumentReference[cbc:ID = 'QR']/cac:Attachment/cbc:EmbeddedDocumentBinaryObject) != '') and (cac:AdditionalDocumentReference[cbc:ID = 'QR']/cac:Attachment/cbc:EmbeddedDocumentBinaryObject[normalize-space(@mimeCode) = 'text/plain'])) )
Reported test
(cac:AdditionalDocumentReference[normalize-space(cbc:ID) = 'QR'] and exists(cac:AdditionalDocumentReference/cac:Attachment/cbc:EmbeddedDocumentBinaryObject) and (cac:AdditionalDocumentReference/cac:Attachment/cbc:EmbeddedDocumentBinaryObject) != '' and (cac:AdditionalDocumentReference/cac:Attachment/cbc:EmbeddedDocumentBinaryObject[normalize-space(@mimeCode) = 'text/plain']))
- Evaluated against
/ubl:Invoice | /cn:CreditNote- Source
vendor/zatca/schematron/20210819_ZATCA_E-invoice_Validation_Rules.xsl:371As 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.
© 2026 Hayatiq AI Solutions F.Z.E. All rights reserved.