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.
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 Nmust contain the hash ofInvoice 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”)
- Value:
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.
- Calculate VAT per line.
- Round to 2 decimal places.
- 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:
- Seller Name
- VAT ID
- Timestamp
- Total with VAT
- VAT Amount
- Invoice Hash
- ECDSA Signature
- Public Key
- 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 Only0100: Simplified Only1100: 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.