BR-KSA-30Signature block does not carry the required signature method

Mutabiq checks Saudi ZATCA Phase 2 e-invoice XML before you submit it: pre-validation against published ZATCA requirements, not an approval by the authority. This page explains one rule, BR-KSA-30.

Validate 5 invoices free

Five checks a month on the Free plan. The file is checked in memory and is never stored.

The message ZATCA prints

[BR-KSA-30]-The document cryptographic stamp (KSA-15) must contain the exact "urn:oasis:names:specification:ubl:dsig:enveloped:xades" value for signature method.

Also cited in this report

  • BR-KSA-28

    [BR-KSA-28]-If the cryptographic stamp (KSA-15) exists in the invoice, this cryptographic stamp (KSA-15) must contain the exact "urn:oasis:names:specification:ubl:signature:1" value for signature information ID.

  • BR-KSA-60

    [BR-KSA-60]-Cryptographic stamp (KSA-15) must exist in simplified tax invoices and associated credit notes and debit notes (KSA-2, position 1 and 2 = 02).

  • BR-KSA-27

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

  • BR-KSA-29

    [BR-KSA-29]-If the cryptographic stamp (KSA-15) exists in the invoice, this cryptographic stamp (KSA-15) must contain the exact "urn:oasis:names:specification:ubl:signature:Invoice" value for referenced signature ID and signature ID.

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.

Signature block does not carry the required signature method

Reported assignature_method_mismatchnot the required signature method

What is wrong

This is a simplified invoice, and no cac:Signature in it carries a cbc:SignatureMethod whose value is exactly urn:oasis:names:specification:ubl:dsig:enveloped:xades. ZATCA refuses the document under BR-KSA-30. That value is a fixed UBL identifier and nothing more: it is not computed, it is not derived from anything in this invoice, and it has no connection to the cryptographic stamp, to a certificate or to a private key. Naming the enveloped XAdES profile here is a label the standard asks for, not a claim about how, or whether, this document was signed. Your ERP writes it out literally and the check is a plain string comparison against it, so a URN with a segment changed, a truncated one, one written in a different case, an algorithm identifier borrowed from the XML-DSig specification, and a document carrying no cac:Signature at all, all fail in exactly the same way. The comparison is made over every cac:Signature in the document, at any depth, and one block carrying the required value satisfies it. This rule and BR-KSA-29 fail independently: a block with the right cbc:ID and no cbc:SignatureMethod draws this one alone. Read a silent BR-KSA-60 carefully too: that rule asks only that a cac:Signature exists and is not empty, so a block carrying the wrong method passes BR-KSA-60 and is still refused here. The rule applies to simplified invoices and their credit and debit notes - the invoice transaction code KSA-2 beginning 02.

What to check in your ERP

Write the constant, exactly: cbc:SignatureMethod inside cac:Signature, with the text urn:oasis:names:specification:ubl:dsig:enveloped:xades, letter for letter and in that case. It can be written unconditionally from the export template: it never varies from one invoice to the next, it does not depend on the signing step having run, and writing it does not stamp the invoice - the stamp itself sits in ext:UBLExtensions and is checked by BR-KSA-28. ZATCA's own sample simplified invoices carry it beside cbc:ID with the value urn:oasis:names:specification:ubl:signature:Invoice, which is the neighbouring rule BR-KSA-29 and fails separately. The usual causes are a template that emits cac:Signature with cbc:ID only, since UBL makes the method element optional; a generic UBL or XAdES library that writes an algorithm URI of its own, typically one from the XML-DSig namespace, into this element; and a value retyped by hand with dsig or xades misspelt. Add or correct the element in the export template.

An attachment on this invoice carries no payload element

Reported aspayload_element_missingthe payload element is missing

What is wrong

BR-KSA-30 is written as three conditions and only the third one is about the signature method. The first two are about attachments: ZATCA evaluates this rule once for every cac:AdditionalDocumentReference/cac:Attachment in the document except the previous invoice hash one, which its tooling routes to a different check, and each of them must carry a cbc:EmbeddedDocumentBinaryObject that is not empty. Here one of those attachments - on a simplified invoice built to ZATCA's requirements this is normally the QR code attachment - has no payload element inside it at all, so the rule fails on that condition and the signature method was never reached. ZATCA refuses the document under BR-KSA-30. This finding is therefore not evidence that anything is wrong with your cac:Signature block: it says an attachment is missing the element that would hold its payload. Under rule packs before 2.0.0, BR-KSA-29 was written over the same two conditions and reported the same defect as well; in SDK 3.4.8, which rule pack 2.0.0 reads, BR-KSA-29 no longer looks at the payload, so of the two signature rules only this one reports it, and the QR rules report the same element.

What to check in your ERP

Fix the attachment, not the signature block. The shape is two levels inside the reference: a cac:Attachment, and a cbc:EmbeddedDocumentBinaryObject inside that, with the base64 payload as its 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 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. If your export writes some document reference of its own beside the QR one, a delivery note or a contract say, that attachment is judged here too, so a block written without its payload for a purpose of your own reaches this rule as well. A payload element that is present but empty is a different finding.

An attachment on this invoice has an empty payload

Reported aspayload_emptythe payload is empty

What is wrong

BR-KSA-30 is written as three conditions and only the third one is about the signature method. The first two are about attachments: ZATCA evaluates this rule once for every cac:AdditionalDocumentReference/cac:Attachment in the document except the previous invoice hash one, which its tooling routes to a different check, and each of them must carry a cbc:EmbeddedDocumentBinaryObject that is not empty. Here one of those attachments - on a simplified invoice built to ZATCA's requirements this is normally the QR code attachment - carries the payload element with nothing in it, so the rule fails on that condition and the signature method was never reached. ZATCA refuses the document under BR-KSA-30. That was measured rather than reasoned out: emptying the QR payload of an otherwise passing simplified invoice returns BR-KSA-30 from ZATCA's own tooling, and under SDK 3.4.8 the QR rules report the same element beside it. So this finding is not evidence that anything is wrong with your cac:Signature block, and the QR findings on the same element are the ones to read beside it.

What to check in your ERP

The element is being written and the value behind it is not, so the mapping produces the attachment unconditionally while the step that fills it is not running or is returning nothing. On a simplified invoice that step is normally the QR generator: check that it runs before the document is serialised and that it is enabled for this document type. Fix the generator or the mapping rather than deleting the empty element, because deleting the QR block moves the document onto BR-KSA-27 for a missing QR reference instead. Your cac:Signature block needs no change for this finding, but it is worth confirming that its cbc:SignatureMethod and cbc:ID carry the two fixed URNs while you are there: this rule only reaches that third condition once the payload is filled, so a wrong URN can be waiting behind this finding.

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(exists(cbc:EmbeddedDocumentBinaryObject) and (cbc:EmbeddedDocumentBinaryObject) != '' and (//cac:Signature/cbc:SignatureMethod) = 'urn:oasis:names:specification:ubl:dsig:enveloped:xades')

Reported test

exists(cbc:EmbeddedDocumentBinaryObject) and (cbc:EmbeddedDocumentBinaryObject) != '' and (//cac:Signature/cbc:SignatureMethod) = 'urn:oasis:names:specification:ubl:dsig:enveloped:xades'
Evaluated against
cac:AdditionalDocumentReference/cac:Attachment
Source
vendor/zatca/schematron/20210819_ZATCA_E-invoice_Validation_Rules.xsl:1354

As 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.

A worked example

A synthetic document from the measured test corpus that trips this rule, shown where it differs from one that passed. Mutabiq's report names the class of the value, never the value itself.

Where it differs from a document that passed

  • This example
  • A document that passed
  <cbc:ID>QR</cbc:ID>  <cac:Attachment>This example:     <cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain"></cbc:EmbeddedDocumentBinaryObject>A document that passed:     <cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain">ARNIYXlhdGlxIFRlc3QgU2VsbGVyAg8zMDAwMDAwMDAwMDAwMDMDFDIwMjYtMDktMDFUMTA6MDA6MDB… (full length: 803)  </cac:Attachment></cac:AdditionalDocumentReference>
Document
bad-36-qr-payload-empty.xml
Mutabiq's verdict
Not passed
Reported as
payload_emptythe payload is empty

Download this example (.xml)Check it in Mutabiq

This page's example, checked by the same rules your own upload goes through. No upload and no sign-in.

Rules evaluated against the same part of the document. One wrong value often reports several of them at once.

Check an invoice

Check your own invoice

© 2026 Hayatiq AI Solutions F.Z.E. All rights reserved.