Direct Answer / Quick Summary:

When submitting electronic invoices to Saudi Arabia's ZATCA Fatoora API under Phase 2, invoices undergo a strict two-tier validation pipeline: XSD Structural Validation (confirming UBL 2.1 syntax conformance) and Schematron Business Rule Validation (enforcing Saudi-specific tax arithmetic and cryptographic requirements).

Top Cause of Rejections:* Arithmetic discrepancies where line item totals do not match the <cac:TaxTotal> summary due to floating-point rounding errors (Error BR-CO-10 / BR-KSA-13).

Cryptographic Hash Errors: Submitting an invoice hash (`<ds:DigestValue>`) calculated after* injecting signature elements instead of hashing the canonicalized skeleton XML (Error BR-KSA-26).

Mandatory Credit/Debit References:* Issuing credit or debit notes without referencing the original invoice's unique UUID inside <cac:BillingReference> (Error BR-KSA-70).

Pre-Flight Testing: Always run XML payloads through ZATCA's offline Java Validation SDK* before transmitting to the live /clearance or /reporting endpoints to prevent API throttling and portal non-compliance flags.


The Two-Stage ZATCA Validation Engine

Understanding where your XML payload fails is the first step toward fixing rejection codes:

Stage 1Schema Parser

XSD Syntax Validation

Checks basic XML structure against OASIS UBL 2.1 schema; rejects unclosed tags or invalid data types

Stage 2Business Engine

Schematron Rules (XSLT)

Evaluates over 120 Saudi business rules (BR-KSA), tax arithmetic, and mandatory country profiles

Stage 3Security Module

Cryptographic Audit

Verifies ECDSA digital signature, X.509 certificate trust anchor, and SHA-256 hash chaining

Stage 4Output Gate

Clearance / Reporting Response

Returns HTTP 200 with status CLEARED/REPORTED, or HTTP 400 with detailed array of error codes


Top 10 ZATCA UBL 2.1 XML Validation Errors & Instant Solutions

The following section breaks down the 10 most common error codes encountered by ERP developers, complete with root causes and concrete code fixes:


1. Error BR-KSA-26 / BR-KSA-27: Cryptographic Hash Mismatch

Error Message: The computed invoice hash does not match the digest value in the SignedProperties or Document.
Root Cause: The developer calculated the SHA-256 hash on the entire completed XML file after inserting the digital signature block <ds:Signature>. This creates a circular dependency error.
The Fix: You must compute the hash on the canonicalized XML skeleton excluding three elements:

1. <cac:Signature>

2. <cac:AdditionalDocumentReference> containing the QR code

3. <cac:AdditionalDocumentReference> containing the cryptographic stamp

xml|Technical Specification / Reference
Verified Schema
<!-- CORRECT INVOICE DIGEST INJECTION (SignedProperties) -->
<ds:Reference Id="invoiceSignedData" URI="">
  <ds:Transforms>
    <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
      <ds:XPath>not(ancestor-or-self::cac:Signature or ancestor-or-self::cac:AdditionalDocumentReference[cbc:ID='QR'])</ds:XPath>
    </ds:Transform>
    <ds:Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11"/>
  </ds:Transforms>
  <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
  <ds:DigestValue>mK7m3VvK4q1a...</ds:DigestValue>
</ds:Reference>

2. Error BR-CO-10 / BR-KSA-13: Tax Arithmetic Rounding Discrepancy

Error Message: Invoice total VAT amount (BT-110) must equal the sum of VAT category amounts (BT-117).
Root Cause: Standard floating-point precision issues in languages like JavaScript, Python, or PHP where fractions of halalas (e.g., 0.005) are rounded differently across invoice lines versus the total tax summary.
The Fix: Enforce BigDecimal or exact 2-decimal rounding (ROUND_HALF_UP) per line item and ensure that:
\sum Line Tax Amount = TaxTotal TaxAmount
xml|Technical Specification / Reference
Verified Schema
<!-- CORRECT TAX SUB-TOTAL CONFORMANCE -->
<cac:TaxTotal>
  <cbc:TaxAmount currencyID="SAR">150.00</cbc:TaxAmount>
  <cac:TaxSubtotal>
    <cbc:TaxableAmount currencyID="SAR">1000.00</cbc:TaxableAmount>
    <cbc:TaxAmount currencyID="SAR">150.00</cbc:TaxAmount>
    <cac:TaxCategory>
      <cbc:ID>S</cbc:ID>
      <cbc:Percent>15.00</cbc:Percent>
      <cac:TaxScheme>
        <cbc:ID>VAT</cbc:ID>
      </cac:TaxScheme>
    </cac:TaxCategory>
  </cac:TaxSubtotal>
</cac:TaxTotal>

3. Error BR-KSA-09: Invalid UUID Format

Error Message: The invoice UUID (BT-484) must be a valid RFC 4122 Version 4 UUID.
Root Cause: Using an auto-incrementing integer, custom ERP string, or non-version 4 UUID format.
The Fix: Generate a strictly compliant 128-bit UUIDv4 string containing hyphen separators:
xml|Technical Specification / Reference
Verified Schema
<!-- CORRECT UUID FORMAT -->
<cbc:UUID>9f8a3c1e-7b42-4f91-8a62-1029481bc39a</cbc:UUID>

4. Error BR-KSA-25: Incorrect Invoice Type Code Name Subtype

Error Message: The invoice type code subtype attribute does not match the declared invoice profile.
Root Cause: Providing incorrect 7-digit bitmask flags in the name attribute of <cbc:InvoiceTypeCode>.
The Fix: Use the exact statutory bitmask format:

* Standard B2B Invoice: 0100000 (Code 388)

* Simplified B2C Invoice: 0200000 (Code 388)

* Export Invoice: 0100000 (Code 388)

xml|Technical Specification / Reference
Verified Schema
<!-- CORRECT STANDARD B2B INVOICE TYPE DECLARATION -->
<cbc:InvoiceTypeCode name="0100000">388</cbc:InvoiceTypeCode>

<!-- CORRECT SIMPLIFIED B2C INVOICE TYPE DECLARATION -->
<cbc:InvoiceTypeCode name="0200000">388</cbc:InvoiceTypeCode>

5. Error BR-KSA-40: Tax Identification Number (TRN) Format Mismatch

Error Message: The VAT registration number of seller or buyer does not match ZATCA specifications.
Root Cause: VAT number does not contain exactly 15 digits, or does not begin with 3 and end with 3.
The Fix: Ensure the VAT number adheres strictly to the regular expression ^3[0-9]{13}3$:
xml|Technical Specification / Reference
Verified Schema
<!-- CORRECT SELLER VAT NUMBER FORMAT -->
<cac:PartyTaxScheme>
  <cbc:CompanyID>310123456700003</cbc:CompanyID>
  <cac:TaxScheme>
    <cbc:ID>VAT</cbc:ID>
  </cac:TaxScheme>
</cac:PartyTaxScheme>

6. Error BR-KSA-31: Issue Date & Time Syntax Error

Error Message: Invoice issue time (BT-3) must conform to ISO 8601 format without time zone offset.
Root Cause: Adding timezone indicators like Z or +03:00 (e.g., 14:30:00+03:00) in <cbc:IssueTime>.
The Fix: Time must be local Saudi time formatted strictly as HH:MM:SS:
xml|Technical Specification / Reference
Verified Schema
<!-- CORRECT DATE & TIME FORMAT -->
<cbc:IssueDate>2026-02-02</cbc:IssueDate>
<cbc:IssueTime>14:35:20</cbc:IssueTime>

7. Error BR-KSA-51: Invalid Previous Invoice Hash (PIH)

Error Message: Previous invoice hash does not match the hash of the preceding invoice or initial seed hash.
Root Cause: Broken hash chaining. In the very first invoice issued by an EGS, the PIH must be a specific Base64 string of 32 zero bytes (NWZlY2ViNjZmZmM4NmY... / SHA-256 of zero). For subsequent invoices, it must match the exact Base64 hash of the immediately preceding invoice.
The Fix: Verify your database's sequential hash retrieval query:
xml|Technical Specification / Reference
Verified Schema
<!-- CORRECT PREVIOUS INVOICE HASH INJECTION -->
<cac:AdditionalDocumentReference>
  <cbc:ID>PIH</cbc:ID>
  <cac:Attachment>
    <cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain">
      NWZlY2ViNjZmZmM4NmY1NzRmMTlhMDY1NzlmMzBhYmNmYzA5ZjY4ZTE4NzMwMTBhNTUxOWZhNmJlYz UniversalInitialSeed==
    </cbc:EmbeddedDocumentBinaryObject>
  </cac:Attachment>
</cac:AdditionalDocumentReference>

8. Error BR-KSA-53: Invoice Counter Value (ICV) Out of Sequence

Error Message: Invoice Counter Value must be sequential and start from 1 for each EGS.
Root Cause: Counter skipped a number (e.g., jumped from 42 to 44), used alphanumeric characters, or reset to 1 on a new calendar month.
The Fix: ICV must be a strictly perpetual, positive integer incremented by 1 per transaction:
xml|Technical Specification / Reference
Verified Schema
<!-- CORRECT SEQUENTIAL INVOICE COUNTER VALUE -->
<cac:AdditionalDocumentReference>
  <cbc:ID>ICV</cbc:ID>
  <cbc:UUID>43</cbc:UUID>
</cac:AdditionalDocumentReference>

9. Error BR-KSA-70: Credit / Debit Note Missing Original Billing Reference

Error Message: A credit note (381) or debit note (383) must reference the invoice that is being amended.
Root Cause: Submitting an adjustment note without linking the original cleared invoice's UUID or serial number.
The Fix: Inject the mandatory <cac:BillingReference> element:
xml|Technical Specification / Reference
Verified Schema
<!-- CORRECT BILLING REFERENCE IN CREDIT NOTE -->
<cac:BillingReference>
  <cac:InvoiceDocumentReference>
    <cbc:ID>INV-2026-00109</cbc:ID>
    <cbc:UUID>9f8a3c1e-7b42-4f91-8a62-1029481bc39a</cbc:UUID>
    <cbc:IssueDate>2026-01-20</cbc:IssueDate>
  </cac:InvoiceDocumentReference>
</cac:BillingReference>

10. Error BR-KSA-14: Malformed QR Code TLV Structure

Error Message: The QR code in the document is not properly encoded according to Tag-Length-Value (TLV) specifications.
Root Cause: Converting the QR payload to JSON or plain string before Base64 encoding, instead of generating raw binary bytes conforming to ASN.1/TLV formatting.
The Fix: Construct the byte array where each field is [Tag_Byte] + [Length_Byte] + [Value_Bytes] and encode the complete binary buffer directly to Base64.

Best Practices: The Pre-Flight Developer Testing Matrix

Statutory Safeguards & Rights Protection

Mandatory protections enforced by MHRSD & Saudi Labor Law

1
Utilize ZATCA Java SDK OfflineAlways validate test invoices using the official 'zatca-java-sdk' CLI validator locally before hitting network endpoints.
2
Maintain Atomic Database LocksImplement database row-level locking on the ICV and PIH generator to prevent race conditions during concurrent multi-threaded billing.
3
Decouple Background QueuingStandard B2B clearance calls must have a 5-second HTTP timeout with automatic exponential backoff to handle transient gateway latency.
4
Audit Schematron Release NotesZATCA occasionally updates Schematron rule definitions; always align with the latest published Data Dictionary.

Frequently Asked Questions (FAQ)

Can an invoice with a validation error still be delivered to a client?

No. If an invoice receives an error during the clearance call, ZATCA rejects the document and assigns status REJECTED. It is legally invalid. Delivering an un-cleared invoice to a B2B client violates tax regulations and prevents the client from deducting input VAT.

What is the difference between a WARNING and an ERROR in ZATCA responses?

An ERROR causes the invoice to be rejected entirely (status: REJECTED). A WARNING allows the invoice to be cleared or reported (status: CLEARED or REPORTED), but flags non-critical data quality issues (such as address formatting) that must be addressed before future submissions.

How can I validate my XML without consuming a live CSID?

You can use the official offline ZATCA E-Invoicing SDK command-line tool (fatoora -validate -invoice invoice.xml) or connect to the official Sandbox Simulation Environment (/e-invoicing/simulation).

Does ZATCA accept Arabic text in XML fields?

Yes. Arabic text is fully supported and recommended for legal entity names, addresses, and line-item descriptions. Ensure the XML document is saved and transmitted using UTF-8 encoding without BOM.

Why does ZATCA reject my credit note even though the calculations are correct?

The most frequent cause is omitting <cac:BillingReference> or referencing an invalid original invoice UUID. Credit and debit notes must always include a valid reference to the original invoice being credited or debited.