Invocie

Top 7 ZATCA Rejection Reasons (and How to Fix Them)

From clock drift to malformed VAT numbers, these are the rejections we see most often in production — with the fix for each.

Invocie Team · December 18, 2025 · 4 min read


ZATCA rejects invoices with terse error codes, and decoding them under deadline pressure is brutal. Here are the top seven we see in production, ordered by frequency, with a tested fix for each.

1. ENT_ICV-001 — Invoice Counter Value out of sequence

ICV must increase monotonically per device. The cause is almost always parallel issuance from two processes against the same EGS. Fix: serialize ICV assignment behind a single source of truth (a database sequence works).

2. ENT_PIH-002 — Previous Invoice Hash mismatch

The hash you submitted as the previous one doesn't match what ZATCA has on file. Cause: someone re-submitted an old invoice or the local cache fell behind. Fix: query Fatoora for the latest cleared hash and reseed your chain.

3. KSA-25 — Tax category code missing or invalid

Each line item needs a UNCL5305 category code: S, Z, E, O, or AE. Common slip: leaving it blank for zero-rated lines. Fix: explicitly emit Z (not omit it).

4. KSA-12 — Seller VAT number malformed

Saudi VAT registration numbers are 15 digits and start with 3, ending with the checksum. A common mistake is submitting the 10-digit Commercial Registration number instead. Fix: pull the VAT from the tax_registrations table by kind='VAT', not from the trade-license field.

5. CLOCK_DRIFT — IssueDateTime more than 30 seconds out of sync

Server clock skew. Fix: NTP sync to pool.ntp.org, every minute, on every host that issues invoices.

6. KSA-08 — Standard invoice missing buyer VAT

B2B invoices in KSA require the buyer's VAT number (TaxID). Simplified (B2C) invoices do not. Fix: branch on InvoiceTypeCode (388 = standard, 388 with subtype 02 = simplified) in your serializer.

7. KSA-19 — Tax amount inconsistent with line totals

Sum of line tax amounts ≠ TaxTotal. Cause is almost always rounding mid-calculation. Fix: round only the final per-rate subtotal (banker's rounding), never per-line.


Related reading

Ship compliant invoices in every market

ZATCA, FTA, Peppol, and global post-audit — one API.

Talk to our team