When you submit an electronic invoice to the Fatoora platform, it may come back with error code 1019. Its meaning is direct: the XAdES signature attached to the invoice is incomplete. That is, the document arrived with a digital signature that is missing mandatory elements required by the signature standard, so the Authority rejects it before clearance because it cannot verify its integrity or the identity of the signer. This error is especially common when the signature is built manually or through a library that does not produce the full signed properties block. This page explains the error from its root: which missing elements produce it, how to read the rejection message, how to correct the signature and resubmit, and how to prevent it recurring for good.
This guide is part of the ZATCA e-invoicing error code reference, specifically within e-invoice signature errors, and it relies on the technical specification for the digital signature. All of this sits within the e-invoicing system from Qoyod. The target audience is the developer, integration analyst, or accountant who manages the technical release and wants a precise understanding of the cause rather than a surface-level step.
ds:SignedInfo with two references
ds:SignatureValue
ds:KeyInfo (the certificate)
SignedProperties: SigningTime + certificate digest
QualifyingProperties referenced from SignedInfo
What error code 1019 means exactly
Error code 1019 A rejection at the digital-signature verification level. The Fatoora platform does not just inspect the invoice content; it also inspects the signature attached to it to confirm it was created in the form the standard requires. If it finds that the signature block is missing mandatory signed properties, or that the signature references are invalid, it stops the invoice and returns this code.
XAdES is an extension of the XML digital signature that adds legal and temporal properties on top of the basic signature. The electronic invoice in Saudi Arabia is signed in this style. A correct signature must contain a signed properties block (SignedProperties) that attests to the time of signing and to the certificate it was signed with. The error 1019 means this block is missing or not properly linked to the signature.
Note the difference between this code and other signature errors. The code 1019 says that the signature is structurally incomplete, meaning it is missing elements. This differs from an error where the certificate is expired or unapproved, or an error where the signature is present and complete but its value does not match the content. Here the problem is in the completeness of the signature, not in its validity, and so the fix is in how it is built, not in the certificate itself.
This distinction is not a theoretical luxury. Many businesses waste hours inspecting and renewing the certificate while the real problem is in the signed properties block that was never generated in the first place. Pinpointing the fault layer precisely shortens the path to the solution and prevents needless changes to settings that are already correct.
When the invoice is rejected due to an incomplete signature, the platform returns a response carrying the invoice status and a list of validation errors. Each error carries a code, a category, and a message. The following block is an illustrative example of a rejection response due to an incomplete XAdES signature. Copy it and compare it with the response structure your system returns.
Copy
with the value
clearanceStatusmeans clearance did not happen, so the invoice was not approved and may not be delivered to the buyer.NOT_CLEAREDconfines the problem to the signature layer, not to the invoice content nor its tax data.categorymeans clearance did not happen, so the invoice was not approved and may not be delivered to the buyer.Signature validationis the precise definition of the cause, and the message indicates that the signed properties are missing or not referenced.codemeans clearance did not happen, so the invoice was not approved and may not be delivered to the buyer.1019confirms there is no stamped copy returned to you.clearedInvoicemeans clearance did not happen, so the invoice was not approved and may not be delivered to the buyer.nullThe practical rule: read
and code together. The category tells you the fault is in the signature, and the code fixes the cause precisely. Do not rely on the wording of the message alone, because it may change slightly between versions while the code stays constant. And if multiple errors come in the response, address the signature errors first because they block approval entirely. category What makes a XAdES signature “complete”
Before fixing the deficiency, you must know the complete form. The XAdES signature in the invoice consists of a
block containing several interlinked parts. Any part that is missing or unlinked produces an “incomplete” signature. The essential parts: ds:Signature : describes what was signed, and contains references (
ds:SignedInfo) pointing to the invoice content and to the signed properties block.ds:Reference: the actual signature value produced by the certificate’s private key.ds:SignatureValue: carries the certificate the invoice was signed with.ds:KeyInfo: containsds:Objectand beneath itxades:QualifyingPropertiesand beneath thatxades:SignedPropertieswhich is the crux of this error.
Inside xades:SignedProperties there must be two indispensable elements: xades:SigningTime which records the time of signing, and xades:SigningCertificate which fixes which certificate signed via a digest (CertDigest) and the issuer reference and serial number (IssuerSerial). The following block shows the full expected structure in brief.
Note the second reference inside ds:SignedInfo: it is the one that links the signature to the SignedProperties block via the two attributes URI together. The category tells you the fault is in the signature, and the code fixes the cause precisely. Do not rely on the wording of the message alone, because it may change slightly between versions while the code stays constant. And if multiple errors come in the response, address the signature errors first because they block approval entirely. Type. The absence of this reference, or its pointing to a non-existent identifier, makes the signed properties present in form but not linked to the signature. The result is the same: an incomplete signature. This is why it is not enough to confirm the block exists; you must confirm it is correctly linked to the signature.
SignedProperties entirely absent
Present but without SigningTime/certificate
QualifyingProperties not referenced
Malformed SignedInfo references
The four causes that produce error 1019
Every case of this error goes back to one of four causes, which we have ordered from most common to rarest. Address the cause matching your case instead of randomly changing the whole signature.
1. The signed properties block is entirely absent
The signature was created in a basic XML style without adding a xades:SignedPropertiesblock. This happens when using a general signing library that does not support XAdES, or when enabling the basic signature and neglecting the signed properties layer. The invoice then carries a signature that is correct in form but does not meet what e-invoicing requires. This is the most common cause among those building an integration for the first time.
2. The signed properties are present but missing elements
The block is present, but it is missing xades:SigningTime or xades:SigningCertificate. The most common form: a SigningCertificate present without a digest (CertDigest) or without the issuer reference and serial number (IssuerSerial). Any missing element inside the block makes it incomplete in the eyes of validation.
3. The signed properties are not referenced from SignedInfo
The block is complete, but there is no reference ( ds:SignedInfo ) insideds:Referencepointing to it, or the value of URI in the reference does not match the Id of the SignedPropertiesblock. Then validation does not count these properties as part of the signature, as if they did not exist. This is the most precise cause and the hardest to detect because the file looks complete to the eye.
4. Malformed SignedInfo references
The reference is present but its Type attribute is wrong, or the digest algorithm (DigestMethod) does not match the standard, or the digest value (DigestValue) was computed on a block modified after signing. All of this makes the link between the signature and the signed properties invalid, so it is rejected as an incomplete signature.
Practical example: an incomplete signature vs. a complete one
The following block shows the first and most common cause: a signature missing a complete ds:Object block, so it has no signed properties at all. This is exactly what produces error 1019 when building the signature with a library that does not support XAdES.
The problem here is in two places: there is no ds:Object carrying the signed properties, and no reference inside ds:SignedInfo pointing to it. To correct it, we add a complete QualifyingProperties block, then add the reference that links it to the signature. The following block shows the corrected part that is added.
After adding these two parts the signature becomes complete: the signed properties are present, and linked to the signature via a URI reference matching the Id. Warning: do not add these elements manually to an already-signed file. Add them in the generation layer before signing, because any modification after signing invalidates the digest value.
How to distinguish error 1019 from other signature errors
Signature errors look alike on the surface, which confuses diagnosis. The practical differences between them:
- Incomplete signature (1019): the signed properties block or its reference is missing. The fix is in the signature-building layer.
- Invalid certificate: the signature is complete but the certificate is expired or unapproved by the Authority. The fix is in renewing or re-registering the CSID certificate.
- Signature value does not match the content: the signature is complete and the certificate is valid, but the content changed after signing so the hash is invalidated. The fix is in regenerating and re-signing.
The rule: determine the error category from the category field in the response, then read the message text. The category says the fault is in the signature, and the message text says the cause is a structural deficiency, not the certificate. This alone directs you to the correct layer immediately. To review the rest of the signature error codes, see e-invoice signature errors.
Where the signature sits in the invoice path
E-invoicing in Saudi Arabia runs on two paths depending on the invoice type, and the signature is present in both but with a different role. Understanding where the signature sits in the path clarifies why error 1019 stops the invoice entirely.
- Clearance for standard tax invoices (B2B): the signed invoice is sent to the platform before it is delivered to the buyer. If the signature is incomplete, clearance stops, so the invoice is neither approved nor delivered.
- Reporting for simplified invoices (B2C): the invoice is issued signed and delivered to the customer, then reported to the platform within the prescribed window. An incomplete signature here fails the reporting and leaves the invoice’s documentation incomplete.
In both cases, the signature is a condition for completing the operation. So error 1019 is not treated as a warning that can be ignored, but as a blocker that stops the invoice from entering the system. Addressing it is a priority before any other error in the response, because an invoice without a complete signature has no value before the Authority no matter how sound the rest of its content is.
This also explains why fixing the content alone does not help. The invoice data may all be correct, the tax number sound, the amounts balanced, and yet it is rejected because the signature is incomplete. The signature is an independent layer on top of the content, and its fault stops everything regardless of the soundness of what lies beneath it.
How the platform checks the signature step by step
To understand the reason for rejection, imagine what the platform does when it receives the signed invoice. Verification passes through ordered stages, and error 1019 falls in one of them specifically. Knowing the stage shortens the diagnosis.
- Structure validation (XSD): the platform confirms the invoice file matches the UBL 2.1 schema. If this succeeds,
XSD_ZATCA_VALIDappears as an information message, as in the response example above. - Checking for the signature block: the platform looks for
ds:Signatureand for theds:Objectthat carries the signed properties. Their absence is the first cause of error 1019. - Checking the completeness of the signed properties: it confirms the presence of
SigningTimetogether. The category tells you the fault is in the signature, and the code fixes the cause precisely. Do not rely on the wording of the message alone, because it may change slightly between versions while the code stays constant. And if multiple errors come in the response, address the signature errors first because they block approval entirely.SigningCertificatewith its two elements. A missing element stops verification here. - Checking the link: it confirms that
ds:SignedInfocontains a correct reference toSignedProperties. This is the most precise thing verification checks and the most hidden when diagnosing.
Error 1019 is raised in the third and fourth stages: when the signed properties are missing their elements, or when they are not linked to the signature. The first stage has its own errors under the structure-validation category, and the second stage may produce an error of the signature being entirely absent. So do not address the error in the content layer as long as the rejection category is signature verification.
A precise point worth noting: linking the signed properties to the signature relies on a digest computed on the SignedProperties block after canonicalizing it (Canonicalization). If the canonical form differs between the moment of computation and the moment of verification, or the digest was computed on a block before it was complete, the values will not match and the same error may appear. So the digest must be computed on the final block after canonicalizing it, not before.
When the error appears depending on how the integration is built
The root cause is one, but the road to it differs by how you built your integration. These are the most common field scenarios:
Integration built manually with a general signing library
If you built the signature with a general XML signing library that does not know XAdES, the output is a basic signature without a signed properties block. This is the most common source of error 1019 among technical teams building the integration from scratch. The solution is not to patch the file, but to adopt a library or module that produces complete XAdES, or to add the block and its reference in the generation layer before signing.
A copied signature template with mismatched identifiers
Many copy a ready signature template then modify it. The common mistake here is that the identifier Id in the SignedProperties block stays different from the value of URI in the reference, so the link breaks. The file looks complete, but it is rejected. Always verify that the identifier and the reference carry the same value after any modification to the template.
Modifying the content after signing
Sometimes the document is signed then its elements are reordered, or spaces are added, or the formatting is changed for layout purposes. Any change after signing invalidates the digest computed on the block. So the signature must be the very last step, and the file must be sent exactly as signed without any subsequent touch.
How to correct the signature and resubmit
Follow the steps in order. Each step addresses a layer on top of the one before it, so do not skip.
- Confirm the signature generator supports XAdES. Verify the tool produces a
xades:QualifyingPropertiesblock, not just a basic XML signature. - Inspect the completeness of the signed properties. Confirm the presence of
SigningTimetogether. The category tells you the fault is in the signature, and the code fixes the cause precisely. Do not rely on the wording of the message alone, because it may change slightly between versions while the code stays constant. And if multiple errors come in the response, address the signature errors first because they block approval entirely.SigningCertificatewith its two elements:CertDigesttogether. The category tells you the fault is in the signature, and the code fixes the cause precisely. Do not rely on the wording of the message alone, because it may change slightly between versions while the code stays constant. And if multiple errors come in the response, address the signature errors first because they block approval entirely.IssuerSerial. - Verify the reference. must contain
ds:SignedInfoa reference toSignedPropertiesmeans clearance did not happen, so the invoice was not approved and may not be delivered to the buyer.URImatching theIdand with the correctTypeattribute. - Regenerate the document after any modification. Any change to the content or to the signature structure invalidates the digest, so do not modify a signed file manually.
- Re-sign with the CSID certificate. Re-sign with your establishment’s certificate then send the document to clearance.
An important point: do not resubmit the rejected invoice as-is after patching the signature textually. Any modification to the signature structure or to the content requires recomputing the digest and re-signing from scratch. Add the missing elements in the generation layer, rebuild the document, then sign it and send it.
Detailing the certificate identity block: CertDigest and IssuerSerial
The most hidden form of deficiency falls inside xades:SigningCertificate. This block does not merely mention the certificate, it fixes it in two complementary ways, and missing either produces an incomplete signature:
CertDigest: a digest of the certificate, made up of the digest algorithm (DigestMethod) and its value (DigestValue). It proves that the referenced certificate is the same one that actually signed, so it cannot be substituted.IssuerSerial: identifies the certificate via the issuer name (X509IssuerName) and the serial number (X509SerialNumber). It links the certificate to the chain of trust that issued it.
The common mistake is that the integration generates CertDigest and neglects IssuerSerial, or vice versa, assuming one is enough. Both are mandatory. Another mistake is that the digest is computed on a certificate different from the one that signed the invoice, so the signature appears complete in form but its digest does not match the certificate attached in ds:KeyInfo. Always confirm that the digest and the serial number belong to the same CSID certificate that signed the document.
The value of SigningTime has a parallel importance. It is not just a decorative timestamp, but part of the signed properties that enter into the digest computation. So it must be written in a correct time format (UTC) inside the block before signing, not added after it. Adding it later invalidates the digest and returns you to square one.
A pre-submission checklist
Before you send any signed invoice to clearance, run through this checklist. Each item closes one of the four doors of error 1019:
- Does the file contain a
ds:Objectblock withxades:QualifyingPropertiestogether. The category tells you the fault is in the signature, and the code fixes the cause precisely. Do not rely on the wording of the message alone, because it may change slightly between versions while the code stays constant. And if multiple errors come in the response, address the signature errors first because they block approval entirely.xades:SignedProperties? - Inside the signed properties, is there a
SigningTimeelement in a correct time format? - Does
SigningCertificatecontainCertDigest(algorithm and value) andIssuerSerial(issuer name and serial number)? - Is there inside
ds:SignedInfoa reference to the signed properties with the correctURImatching theIdand with the correctTypevalue? - Does the certificate digest in
CertDigestbelong to the same certificate attached inds:KeyInfo? - Is the signature the last step, with the content never modified after it in any way?
If you answered yes to every item, the signature is complete and error 1019 will not come back to you. And if you stumble on an item, you have pinpointed the cause precisely and know the layer to address. This checklist is the fastest path to self-diagnosis before resorting to reading the full response.
Let Qoyod build a complete XAdES signature on your behalf
Qoyod generates the signed properties block and its references, and signs the invoice with the CSID certificate automatically, so error 1019 never reaches you in the first place. Start your free trial and issue signed invoices compliant with the Authority.
How to prevent error 1019 recurring in the future
This error is structural in the signature layer, so preventing it is in how it is built, not in addressing it after rejection. Take these measures:
- Adopt a signing library that explicitly supports XAdES, and pin its version so its behavior does not suddenly change.
- Add a local check before submission that rejects any document missing
SignedPropertiesor its reference insideds:SignedInfo. - Sign as the last step in the path, after the invoice content is complete, so the content does not change after signing and invalidate the digest.
- Monitor the response code on every submission, and log
categorytogether. The category tells you the fault is in the signature, and the code fixes the cause precisely. Do not rely on the wording of the message alone, because it may change slightly between versions while the code stays constant. And if multiple errors come in the response, address the signature errors first because they block approval entirely.codein your records to catch any deviation early.
The general idea is that an incomplete signature is not fixed by patching, but prevented at the source. The stricter the generation layer is in producing the signed properties block and linking it to the signature, the lower the chance that an incomplete document reaches the platform in the first place.
How Qoyod helps you avoid this error
Qoyod manages the entire signature layer on your behalf. It generates the xades:SignedProperties block with all its mandatory elements: the signing time, the certificate digest, and the issuer reference and serial number. Then it adds the reference inside ds:SignedInfo that links this block to the signature in the form the standard requires. So you neither build the signature manually nor worry about a missing element in it.
Qoyod also manages your establishment’s CSID certificate automatically, and uses it to sign every invoice without your intervention. And because the signature is built complete every time, error 1019 never reaches you in the first place, and the invoice passes to clearance on the first submission. Your only responsibility remains registering the certificate with the Authority at setup, and Qoyod guides you through this step.
To understand the full technical structure, see technical specification for the digital signature, and to review the rest of the error codes, see ZATCA e-invoicing error code reference.
Confirm XAdES support
Complete SignedProperties
Reference it from SignedInfo
Re-sign with CSID
Frequently asked questions
What is the difference between error 1019 and an expired or unapproved certificate error?
Error 1019 means the signature structure is missing mandatory elements, i.e. a problem in the signature completeness . As for the expired or unapproved certificate error, it means the signature is structurally complete but the certificate it was signed with is invalid. The first is fixed in the signature-building layer, and the second is fixed in the certificate settings.
Which elements must the SignedProperties block contain?
It must contain the xades:SigningTime which records the time of signing, and xades:SigningCertificate that fixes the certificate via a digest (CertDigest) and the issuer reference and serial number (IssuerSerial). Missing any element of these produces the same error.
Why does the error appear despite a SignedProperties block being present in the file?
Because the block being present is not enough. A reference (ds:Reference) inside ds:SignedInfo means clearance did not happen, so the invoice was not approved and may not be delivered to the buyer. URI matching the Id must point to it with the correct Type value. Without this reference, verification does not count it as part of the signature.
Do I resubmit the rejected invoice as-is after fixing the signature?
No. Any modification to the signature structure or to the content invalidates the digest, so you must regenerate the document and re-sign it with the CSID certificate before resubmitting to clearance. Fix the layer, regenerate, then sign and send.
What is XAdES and why does e-invoicing require it?
XAdES is an extension of the XML digital signature that adds legal and temporal properties on top of the basic signature, such as the signing time and the identity of the signing certificate. E-invoicing requires it because it proves who signed the invoice and when, and makes the signature verifiable independently of the system that created it.
How does Qoyod help you avoid this error?
Qoyod builds a complete XAdES signature automatically: it generates the signed properties block with its elements, links it to the signature via the correct reference, and signs with the CSID certificate managed inside the system. So you do not need to build the signature manually, and error 1019 does not reach you.