ZATCA Troubleshooting

Top 15 ZATCA e-Invoice rejection errors and how to fix them

A developer-grade guide to the most common ZATCA Phase 2 rejection errors. We analyze XML validation failures, cryptographic stamp issues, and PIH (Previous Invoice Hash) errors with copy-paste fixes.

Qeemah Team 10 min read
ZATCA Error Codes Debugging Guide

ZATCA’s validation engine is unforgiving. A single whitespace error in your XML or a rounding difference of 0.01 SAR can cause a Rejected or Failed status.

At Qeemah, we’ve debugged thousands of clearance requests. Here are the top 15 rejection errors we see and exactly how to fix them. Need to onboard first? Check our Fatoora Saudi portal guide for CSID setup.

The “Showstopper” Errors (Critical)

1. Cryptographic Stamp Mismatch

Error: The cryptographic stamp is invalid. Why it happens: You modified the XML after signing it, or your canonicalization (C14N) logic is flawed. Fix: Ensure you are hashing the canonicalized version of the invoice, not the raw string.

<!-- Wrong: Hashing this with whitespace -->
<cbc:ID> INV-001 </cbc:ID>
<!-- Right: Hashing strictly normalized XML -->
<cbc:ID>INV-001</cbc:ID>

The signature must be the last thing added before embedding in the UBL extensions.

2. Hash Chain Failure (PIH)

Error: The Previous Invoice Hash (PIH) does not match the computed hash. Why it happens: You are sending Invoice #5 but linking it to the hash of Invoice #3. Fix:

  • Strict Sequencing: Invoice N must contain the hash of Invoice N-1.
  • The First Invoice: If it’s the very first invoice of the EGS (E-Invoicing Generation Solution), the PIH must be a base64 encoded SHA256 hash of “0” (zero).
    • Value: NWZl... (Hash of “0”)

3. Invalid UUID (KSA-2)

Error: BR-KSA-03: The UUID must be a universally unique identifier. Why it happens: Reusing UUIDs or using non-standard formats. Fix: Generate a fresh Version 4 UUID for every new document.

<cbc:UUID>550e8400-e29b-41d4-a716-446655440000</cbc:UUID>

Calculation & VAT Errors

4. Line Item Rounding (BR-S-09)

Error: BR-S-09: The sum of the line item amounts does not equal the total invoice amount. Why it happens: (Price * Qty * VAT) calculated per line vs. on the total. Fix: ZATCA requires Line Level precision.

  1. Calculate VAT per line.
  2. Round to 2 decimal places.
  3. Sum the rounded values. Do not sum first and then apply VAT.

5. Incorrect Tax Category Code

Error: BR-KSA-EN16931-12: The tax category code is invalid. Why it happens: Using S (Standard) for an export invoice or Z (Zero-rated) without a reason code. Fix:

  • Standard (15%): Code S
  • Zero Rated (0%): Code Z (Requires cbc:TaxExemptionReasonCode)
  • Exempt: Code E

6. Missing VAT Registration Number (VRN)

Error: BR-KSA-26: Buyer VAT number is required for B2B. Why it happens: Sending a “Standard” invoice (B2B) but treating it like a “Simplified” invoice (B2C). Fix: If InvoiceTypeCode is 0100000 (Standard), you must include the buyer’s VAT ID in cac:AccountingCustomerParty.

Structural & XML Errors

7. Missing ZATCA UBL Extensions

Error: The UBL extension for ZATCA is missing. Why it happens: Using a standard UBL 2.1 generator without ZATCA-specific wrappers. Fix: Your XML must have the <ext:UBLExtensions> block containing the QR code, Signature, and Signed Properties.

8. Malformed QR Code

Error: KSA-QR-01: The QR code is not decodable. Why it happens: The TLV (Tag-Length-Value) encoding is wrong. Fix: The QR code is not just a URL. It is a Base64 string of TLV data containing:

  1. Seller Name
  2. VAT ID
  3. Timestamp
  4. Total with VAT
  5. VAT Amount
  6. Invoice Hash
  7. ECDSA Signature
  8. Public Key
  9. Stamp Signature

For the full technical breakdown, see our ZATCA QR Code Requirements & TLV Encoding guide.

9. Future Dating

Error: The IssueDate cannot be in the future. Why it happens: Server timezone mismatch. Fix: Ensure your server time is synced to Saudi Standard Time (UTC+3).

10. Sequential Number Gaps

Error: Metric: Invoices must be sequential. Why it happens: Deleting an invoice from your database. Fix: Never delete an invoice. If you made a mistake, issue a Credit Note. The sequence INV-001, INV-002, INV-004 will flag an audit.

Onboarding & Certificate Errors

11. OTP Invalid or Expired

Error: Invalid OTP. Why it happens: Using an OTP generated > 1 hour ago or for the wrong portal (Sandbox vs. Simulation). Fix: Generate a new OTP from the Fatoora portal immediately before running your onboarding script.

12. CSR Mismatch

Error: The Certificate Signing Request (CSR) organization does not match. Why it happens: The VAT ID in your CSR config (cnf file) doesn’t match the VAT ID of the Fatoora account login. Fix: Double-check your openssl config. The UID field in the Subject must be your 15-digit VAT number.

13. Wrong Invoice Type for CSID

Error: Compliance check failed. Why it happens: Trying to clear a Standard Invoice using a CSID generated for Simplified Invoices (or vice versa). Fix: When onboarding, specify correctly:

  • 1000: Standard Only
  • 0100: Simplified Only
  • 1100: Both

”Invisible” Errors (Logic)

14. Missing Arabic Translation

Error: Rule: Invoice must contain Arabic. Why it happens: Sending English-only descriptions. Fix: ZATCA requires Arabic for core fields.

<cbc:Description>Consulting Services | خدمات استشارية</cbc:Description>

15. Nominal Invoice Errors

Error: Price cannot be zero. Why it happens: Giving a 100% discount incorrectly. Fix: Do not set Price to 0. Set the Price to the actual value, and use a cac:AllowanceCharge to apply the discount.


Tired of debugging XML?

You shouldn’t have to be an XML expert to sell your products.

Qeemah handles all these validations automatically. We catch these errors before they reach ZATCA, ensuring your business never stops running.

Validate My XML Now

Share this article

Chat with us on WhatsApp