StartPOS ZATCA Software Pricing Free Trial
ZATCA Compliance Guide · August 2026

ZATCA Phase 2 Invoice Rejection Reasons: 12 Causes, Official Error Codes, and How to Fix Each

By Gulf Union Ozone ZATCA Team · 20 min read · Last verified against ZATCA regulations August 2026

Across our first 10,000 ZATCA Phase 2 clearance submissions in Saudi Arabia, we have seen every rejection pattern that ZATCA's Fatoorah portal returns. Most of them trace back to fewer than twelve root causes — and every single one has a deterministic fix. This guide documents all of them.

If you have just received a rejection from the Fatoorah API and need to know what error code KSA-REJECT-02 means, why your hash chain broke, or what the financial penalty for repeated rejections looks like, you are in the right place. If you are building a pre-go-live integration and want to understand what ZATCA checks before rejecting, this guide covers that too.

For background on how ZATCA Phase 2 works before diving into rejection reasons, see our complete ZATCA Phase 2 e-invoicing explained guide.

Disclaimer: Penalty figures cited in this article are based on VAT Implementing Regulations Article 49 as published by ZATCA. Always confirm current enforcement guidance with a licensed Saudi tax advisor.

Already receiving ZATCA rejections?

StartPOS by Gulf Union Ozone has maintained a 0% rejection rate across all Saudi ZATCA Phase 2 deployments. One-time license from SAR 7,500. Live in 24–48 hours.

Explore StartPOS ZATCA Phase 2 Software →

What "Rejected" Actually Means in ZATCA Phase 2

When ZATCA's Fatoorah API rejects an invoice, it means the portal has evaluated the submitted XML document against its validation rules and determined that the invoice cannot be accepted into the national e-invoicing record. The portal returns an HTTP error response that includes one or more structured error codes identifying exactly which validation rule failed.

A rejection is different from a warning. ZATCA's Fatoorah API returns two response types for accepted invoices: accepted (all validations passed) and accepted with warnings (passed all mandatory validations but triggered advisory notices). A rejected invoice fails at least one mandatory validation and is not stored in ZATCA's records.

The legal implications differ sharply by invoice type:

  • B2B standard invoice (clearance mode): A rejected invoice cannot be legally delivered to the buyer. The transaction is legally incomplete until a corrected invoice is submitted and cleared. Delivering an uncleared B2B invoice exposes both buyer and seller to compliance risk.
  • B2C simplified invoice (reporting mode): The invoice may have already been handed to the customer, but it is not ZATCA-compliant until successfully reported. Unreported invoices accumulate as a compliance gap that ZATCA can audit at any time.
  • Credit and debit notes: Both follow the submission mode of the original invoice. A credit note referencing a cleared B2B invoice must also go through clearance. A rejected credit note means the return is not legally recognised by ZATCA.

ZATCA retains a log of all submission attempts, including rejected ones. During a ZATCA audit, a pattern of repeated rejections is evidence of a systemic compliance failure and can trigger escalated penalty assessment.

Clearance vs. Reporting Mode: Different Rejection Consequences

Understanding which submission mode your invoice uses is essential to understanding the severity of a rejection. The two modes have different timing requirements, different rejection consequences, and different retry rules.

Feature Clearance Mode (B2B) Reporting Mode (B2C)
Invoice type Standard tax invoice — B2B transactions where buyer provides VAT number Simplified tax invoice — B2C transactions to end consumers
When to submit Before delivering the invoice to the buyer Same day of issuance (before midnight KSA time)
ZATCA response required? Yes — buyer cannot receive invoice until ZATCA returns a clearance stamp No — invoice can be delivered before ZATCA confirms receipt
Rejection blocks delivery? Yes — must fix and resubmit before completing the transaction No — but unreported invoice creates a compliance gap
API response time Typically 1–3 seconds under normal load Accepted asynchronously; confirmation usually under 5 seconds
Rejection impact on buyer Buyer cannot claim input VAT until clearance is obtained No direct impact — buyer is an end consumer with no VAT to reclaim
Retry on rejection Must fix and resubmit same ICV; transaction stays open Must fix and resubmit before midnight; if missed, document the sequence gap

The practical takeaway: a rejection in clearance mode stops the transaction dead and creates a bottleneck at the point of sale or dispatch. This is why multi-branch retail businesses, wholesale distributors, and any operation with high B2B volume need a POS system that validates invoices locally against ZATCA's rules before ever calling the Fatoorah API — eliminating rejections before they occur rather than recovering from them.

12 Most Common ZATCA Invoice Rejection Reasons

1. XML Schema Violation (KSA-REJECT-01)

What it is: The submitted XML document does not conform to ZATCA's UBL 2.1 KSA profile. Common variants include missing mandatory elements, incorrect element ordering, wrong namespace declarations, or use of field values that are not in ZATCA's allowed code lists.

Why it happens: This is typically a software configuration error rather than a user error. It occurs when the invoicing system has not been validated against ZATCA's official SDK, when an update to the ZATCA technical specifications has changed a field requirement that the software has not yet implemented, or when custom field mappings have been added that violate the schema.

Fix: Validate your XML against ZATCA's published XSD schema and Schematron rules using the ZATCA e-Invoicing SDK before submission. Do not rely on API rejection as your validation mechanism — run local schema validation on every invoice before sending it to the Fatoorah API.

2. PIH (Previous Invoice Hash) Mismatch (KSA-REJECT-02)

What it is: The PIH field in the submitted invoice — which must contain the SHA-256 hash of the previous accepted invoice's XML — does not match the value that ZATCA has recorded as the last accepted hash in the chain.

Why it happens: The invoice hash chain is ZATCA's primary anti-tampering mechanism. Every invoice's PIH must exactly match the hash ZATCA computed for the previous accepted invoice. Chain breaks occur when: a server restarts and loses the in-memory cached hash without persisting it to storage; a rejected invoice's hash is incorrectly stored as the chain tip (ZATCA does not advance the chain on rejection); or multiple POS terminals share a single submission queue but update PIH from different cached copies.

Fix: Persist the PIH after each successful submission to a database, not only to application memory. On startup or failover, retrieve the last known accepted hash from your local database, then verify it against ZATCA's API before resuming submissions. Never update the stored PIH from a rejected submission. If the chain has already broken, retrieve the correct chain tip from ZATCA's Fatoorah portal and rebuild from that point.

3. Invalid or Missing Digital Signature (KSA-REJECT-03)

What it is: The XML digital signature attached to the invoice is absent, malformed, or cannot be verified against the CSID/CCSID certificate registered with ZATCA for this device.

Why it happens: Every ZATCA Phase 2 invoice must be signed with an ECDSA-256 digital signature using the private key associated with the device's production CCSID certificate. Signature failures occur when: the CCSID certificate has expired and not been renewed; the signing operation references a key that does not match the registered certificate; the XML is modified after signing (for example, by a middleware layer that reformats the document); or the certificate was onboarded in sandbox mode and is being used against the production Fatoorah endpoint.

Fix: Re-sign the invoice with the current production CCSID certificate and resubmit. Set up automated certificate expiry monitoring with at least a 30-day advance renewal window. Ensure no post-signing XML transformation occurs in your submission pipeline. Confirm that production CCSID credentials are being used against the production Fatoorah endpoint, not the sandbox endpoint.

4. Seller TIN Mismatch (KSA-REJECT-04)

What it is: The seller's Tax Identification Number (TIN) declared in the invoice XML does not match the TIN associated with the CCSID certificate that signed the invoice.

Why it happens: ZATCA links each CCSID certificate to a specific TIN during the device onboarding process. If your business has multiple VAT registrations (for example, a parent company and a branch entity), a mismatch occurs if the wrong TIN is configured in the invoice template. This also occurs when a testing CSID from one TIN is accidentally deployed in a production environment configured for a different TIN.

Fix: Verify your TIN in the ZATCA Fatoora portal and confirm it matches the value your software inserts into the SellerID field. Confirm that the CCSID certificate onboarded for each device was registered under the correct TIN from the start. For multi-entity operations, maintain separate CCSID certificates per legal entity and ensure they are deployed to the correct POS devices.

5. ICV (Invoice Counter Value) Out of Sequence or Duplicate (KSA-REJECT-05)

What it is: The Invoice Counter Value (ICV) — a sequential integer that must increment by exactly 1 with each invoice — is either out of order, duplicated, or skips a number in the sequence.

Why it happens: ICV failures are almost always a software architecture problem. The ICV counter must be managed server-side with atomic increment operations, not client-side or in application memory. Common failure modes include: concurrent invoice submissions from multiple terminals sharing the same counter without locking; a server restart that resets the counter to a cached value that has fallen behind the actual submission sequence; incrementing ICV on a rejection (incorrect — ICV only advances on successful acceptance); or running two POS devices with the same CCSID certificate (which ZATCA explicitly prohibits — one CCSID per device).

Fix: Move ICV management to a centralised database with transactional, atomic increment. Use a database sequence or equivalent that guarantees no two invoice submissions ever receive the same ICV value. Never increment ICV on a rejected submission — retry with the same ICV. On a sequence gap, contact ZATCA support to formally close the gap before continuing.

6. Duplicate UUID (KSA-REJECT-06)

What it is: The UUID assigned to this invoice already exists in ZATCA's records, associated with a previously submitted invoice.

Why it happens: ZATCA requires each invoice to carry a globally unique identifier formatted as an RFC 4122 version 4 UUID. Duplicates occur when invoicing software reuses UUIDs (for example, copying a previous invoice as a template without regenerating the UUID), when a failed submission is retried with a corrected document but the same UUID is intentionally or accidentally reused, or when test-environment UUIDs are accidentally submitted to production.

Fix: Generate a new RFC 4122 v4 UUID for every invoice, every time. On a retry after a rejected submission, generate a new UUID for the corrected invoice — do not reuse the UUID from the failed attempt. Ensure your testing and production environments use completely separate UUID namespaces.

7. Invoice Timestamp Errors (KSA-REJECT-07)

What it is: The invoice's issue date and time are invalid — typically future-dated beyond the allowed tolerance, formatted incorrectly, or using a time zone offset other than UTC+3 (Arabia Standard Time).

Why it happens: ZATCA validates invoice timestamps against its own server clock. Invoices dated in the future (beyond a small tolerance window) are rejected. Timestamp format errors occur when the system clock on the POS device is not synchronised, or when the datetime field is serialised in a non-compliant format.

Fix: Use NTP-synchronised server time for all invoice timestamps. Format timestamps as YYYY-MM-DDThh:mm:ssZ with the UTC offset specified. Ensure POS devices sync their clocks on startup and alert staff if the clock drift exceeds 2 minutes.

8. QR Code Data Mismatch (KSA-REJECT-08)

What it is: The TLV-encoded QR code embedded in the invoice does not match the declared invoice content. ZATCA's validator extracts and checks the QR code fields — seller name, VAT number, timestamp, total amount, VAT amount, and invoice hash — against the XML body.

Why it happens: QR code mismatches most often occur with Arabic text in the seller name field. Arabic characters encoded in Base64 TLV must use UTF-8 encoding. If the TLV encoder uses a non-UTF-8 encoding (for example, Windows-1256 or ISO-8859-6), the decoded seller name will not match the XML seller name field. They also occur when the invoice totals are rounded differently between the QR and the XML.

Fix: Always encode TLV strings as UTF-8. Test QR code decoding against ZATCA's verification tool before going live. Use the same rounding function for QR code totals and XML invoice totals — compute once and reference the same computed value in both fields.

9. Missing Mandatory Field (KSA-REJECT-09)

What it is: A field that ZATCA requires to be present in the invoice XML is absent or empty. The error response will specify the XPath location of the missing field.

Why it happens: Mandatory field omissions typically happen during initial integration when not all ZATCA-required fields have been mapped to data sources. They also occur when optional fields in a generic UBL 2.1 implementation are left blank but are mandatory under ZATCA's KSA profile — for example, the buyer's VAT number on a B2B standard invoice, or the payment means code on a simplified invoice.

Fix: Review the specific XPath in the rejection error response. Map every mandatory ZATCA field to a data source in your invoicing system. Run compliance validation against ZATCA's full field requirement list before go-live.

10. VAT Rate or Calculation Error (BR-KSA-31)

What it is: The VAT amount declared on the invoice does not match the result of applying the declared VAT rate to the taxable amount, within ZATCA's accepted rounding tolerance. This triggers business rule BR-KSA-31.

Why it happens: Saudi VAT is currently 15%. On invoices with multiple line items at different quantities, rounding errors accumulate if VAT is computed on individual lines and summed, versus computed on the total taxable amount. ZATCA requires a specific rounding approach: VAT is calculated per line item, rounded to 2 decimal places per line, and summed. Line-level and invoice-level amounts must all agree within ZATCA's tolerance of SAR 0.01.

Fix: Implement ZATCA's specified rounding methodology exactly. Round at line level (2 decimal places), then sum. Do not re-apply the VAT rate to the line total sum — use the pre-rounded line VAT amounts. For multi-rate invoices (15% standard, 5% tourism, 0% zero-rated, exempt), ensure each rate category is calculated and reported separately in the correct VAT breakdown section of the UBL XML.

11. Credit/Debit Note Missing Original Invoice Reference (BR-KSA-44)

What it is: A credit or debit note has been submitted without a reference to the original invoice it is adjusting, or the reference provided does not match any invoice in ZATCA's records. This triggers business rule BR-KSA-44.

Why it happens: Credit and debit notes must include the original invoice's UUID in the BillingReference/InvoiceDocumentReference/ID field of the UBL XML. The referenced UUID must match an invoice that was previously accepted and cleared by ZATCA. Errors occur when the original invoice's UUID was not stored at time of clearance, or when staff manually issue a credit note for an invoice that was itself rejected and never cleared.

Fix: Store the ZATCA-accepted UUID of every cleared invoice in your database at the time of successful submission. When generating a credit note, retrieve and insert the stored UUID from the original transaction. Ensure your software flags any attempt to issue a credit note against an invoice that was not successfully cleared — such a credit note will always be rejected.

12. CSID Certificate Expired or Not Activated (HTTP 401)

What it is: The authentication token in the submission request is rejected by ZATCA's API with an HTTP 401 Unauthorized status. This means the CCSID certificate used to authenticate the submission has expired, been revoked, or was never successfully activated for the production environment.

Why it happens: CCSID production certificates issued by ZATCA have a defined validity period (typically 3 years). Upon expiry, all submissions from that device are rejected. This also occurs when a compliance CSID (sandbox certificate) is used against the production Fatoorah endpoint — the sandbox and production environments use different certificate authorities.

Fix: Renew the CCSID certificate via the ZATCA Fatoora portal before expiry. Set up automated monitoring to alert you 60 and 30 days before the certificate's notAfter date. If already expired, the certificate must be renewed through ZATCA's onboarding API and the new certificate deployed to all affected devices before submissions can resume.

Official ZATCA Fatoorah API Error Code Reference Table

The following table covers the full range of rejection codes returned by ZATCA's Fatoorah API, including the complete KSA-REJECT series, business rule codes, and HTTP response codes. Use it to look up any code you receive in a rejection response.

Error Code HTTP Status Category Meaning Fix Steps
KSA-REJECT-01 400 Schema XML does not conform to UBL 2.1 KSA profile — missing element, wrong namespace, or invalid code list value Validate XML against ZATCA XSD and Schematron rules using ZATCA SDK before submission
KSA-REJECT-02 422 Cryptography PIH (Previous Invoice Hash) does not match ZATCA's record of the last accepted invoice hash Retrieve last accepted hash from persistent storage; never update PIH from a rejected invoice; verify chain before resuming
KSA-REJECT-03 422 Cryptography Digital signature is missing, malformed, or cannot be verified against the registered CCSID certificate Re-sign with current production CCSID; verify no post-signing XML modification; check certificate validity dates
KSA-REJECT-04 422 Identity Seller TIN declared in the XML does not match the TIN registered for the signing CCSID certificate Verify TIN in ZATCA Fatoora portal; ensure CCSID was onboarded under the correct TIN; check multi-entity deployments
KSA-REJECT-05 422 Sequence ICV (Invoice Counter Value) is out of sequence, duplicated, or skips a number Use server-side atomic counter with database locking; never increment ICV on rejection; one CCSID per device only
KSA-REJECT-06 422 Business Rule UUID already exists in ZATCA records, associated with a different invoice Generate fresh RFC 4122 v4 UUID for every invoice; do not reuse UUIDs on retry; separate test and production UUIDs
KSA-REJECT-07 422 Timestamp Invoice issue date or time is invalid — future-dated beyond allowed tolerance, or formatted incorrectly Use NTP-synchronised server time; format as ISO 8601 with UTC+3 offset; alert on clock drift exceeding 2 minutes
KSA-REJECT-08 422 QR Code TLV-encoded QR code data does not match the declared invoice content — totals or seller name mismatch Encode all TLV strings as UTF-8; use same rounding function for QR totals and XML totals; verify with ZATCA QR decoder tool
KSA-REJECT-09 400 Missing Field A mandatory field required by ZATCA's KSA profile is absent or empty Inspect XPath in error response; map all mandatory ZATCA fields to data sources; run full field coverage test before go-live
KSA-REJECT-10 422 Business Rule VAT rate code is invalid or not in ZATCA's allowed VAT category code list Use only ZATCA-permitted VAT category codes: S (standard 15%), Z (zero-rated), E (exempt), O (out-of-scope)
KSA-REJECT-11 422 Business Rule Line-item VAT amount is inconsistent with the declared VAT category rate Recalculate line VAT amounts using exact ZATCA rounding rules; ensure exempt lines carry zero VAT amount
KSA-REJECT-12 422 Business Rule Invoice total amounts (taxable amount, VAT total, gross total) do not match the sum of line-item amounts Compute totals by summing pre-rounded line values; do not re-apply rates to invoice-level totals; verify within SAR 0.01 tolerance
KSA-REJECT-13 401 Certificate CCSID certificate not found in ZATCA registry or device onboarding not completed for the production environment Complete ZATCA production onboarding via the Fatoora portal; do not use sandbox CCSID against production endpoint
KSA-REJECT-14 422 Duplicate An invoice with the same ICV number has already been accepted — the submission is a duplicate Verify whether the original submission succeeded before retrying; if a success response was received, the invoice is already registered
KSA-REJECT-15 422 Business Rule Credit or debit note references a UUID that does not exist in ZATCA's accepted invoice records Only issue credit notes against invoices that were successfully cleared; retrieve stored UUID from the original cleared invoice record
KSA-REJECT-16 422 Configuration Invoice type code is invalid for the declared transaction type — for example, a simplified invoice type code used with a B2B buyer VAT number Use invoice type code 388 (standard) for B2B; 381 (credit note); 383 (debit note); simplified invoices use type 388 with sub-type 02
KSA-REJECT-17 422 Window Invoice submitted outside the allowed submission window — reporting-mode invoice submitted after midnight of the issuance date Submit B2C invoices before midnight KSA time on the day of issuance; implement queue-and-retry with timestamp monitoring
BR-KSA-31 422 Business Rule VAT amount calculation does not match declared rate applied to taxable amount, outside ZATCA rounding tolerance Apply ZATCA rounding rules: round VAT per line to 2 decimal places, sum rounded values; do not re-apply rate to total taxable amount
BR-KSA-44 422 Business Rule Credit or debit note missing BillingReference element with the original invoice UUID Include original invoice UUID in BillingReference/InvoiceDocumentReference/ID; store cleared UUIDs at time of acceptance
HTTP 400 400 Request Malformed API request — invalid JSON body, missing required headers, or Base64-encoded XML could not be decoded Verify API request body encoding; ensure Content-Type header is application/json; confirm Base64 encoding of XML is valid
HTTP 401 401 Authentication CCSID token is expired, revoked, or incorrect — API authentication failed Renew CCSID via ZATCA Fatoora portal; deploy renewed certificate to device; monitor certificate expiry 30 days in advance
HTTP 422 422 Validation Invoice XML passed structural parsing but failed one or more business rule validations — inspect the validationResults.errorMessages array in the response body for specific codes Parse the full error array from the response body; each entry includes the specific rule code and XPath location of the failure

Step-by-Step: What to Do Immediately After a Rejection

When ZATCA's Fatoorah API returns a rejection, the response body contains the information you need to diagnose and fix the problem. Here is the correct sequence:

  1. Log the full API response immediately. The rejection response includes the HTTP status code, the validationResults object, and one or more errorMessages entries. Each entry contains the rule code, the severity (ERROR vs WARNING), and often the XPath location of the failing field. Log all of this — do not only log the HTTP status code.
  2. Do not increment ICV and do not update PIH. On a rejection, neither the Invoice Counter Value nor the Previous Invoice Hash should advance. Your system should hold the current ICV and PIH values for the retry. If your software has already incremented these, you will need to roll them back before the retry.
  3. Identify the root cause from the error code table above. Look up each returned error code in the reference table. If you receive multiple error codes in a single rejection, address all of them before retrying — a partial fix that resolves one code but not another will result in another rejection.
  4. Fix the underlying data or configuration problem. For data errors (wrong TIN, missing field, rounding mismatch), fix the invoice data. For configuration errors (expired certificate, wrong endpoint, incorrect counter), fix the system configuration. Never retry without a confirmed fix.
  5. Regenerate the invoice XML with the fix applied. For most rejection types, you need to regenerate the complete XML — not just patch a single field. This is because many fields are interdependent: the digital signature covers the entire XML, the QR code hash covers the canonicalised document, and the PIH depends on the invoice content.
  6. Re-sign and resubmit with the same ICV. Use the same ICV number from the failed attempt. Generate a new UUID for the corrected invoice. Sign with the current production CCSID. Submit to the Fatoorah API.
  7. Document the sequence if a gap has occurred. If the rejection caused a time gap in your submission log (especially for reporting-mode invoices), document it with timestamps, error codes, and resolution steps. ZATCA may request this documentation during an audit to explain submission gaps.

ICV and PIH Chain: What Happens When the Counter Goes Wrong

The ICV (Invoice Counter Value) and PIH (Previous Invoice Hash) are the two most technically complex fields in ZATCA Phase 2, and they are the source of the most operationally damaging rejections. Understanding how they work is essential for any business with multiple POS terminals, high transaction volume, or a history of connectivity issues.

How the ICV Counter Works

The ICV is a simple sequential integer, starting at 1 for the first invoice ever submitted from a given CCSID-registered device. Every successfully submitted invoice must have an ICV exactly 1 greater than the previous accepted invoice. ZATCA does not accept gaps in the sequence and does not accept the same ICV twice.

The critical rule: ICV only advances on a successful ZATCA acceptance. A rejected invoice does not advance the ICV. An offline invoice that is queued and not yet submitted does not advance the ICV. If your system increments ICV on rejection or on invoice generation (rather than on successful acceptance), you will create gaps that require manual reconciliation with ZATCA.

For multi-terminal operations, each CCSID certificate is device-specific. You cannot share a CCSID across two POS terminals. Each terminal has its own ICV sequence, its own hash chain, and its own certificate. This means a 10-terminal retail operation in Jeddah has 10 independent CCSID certificates and 10 independent ICV sequences, managed independently by each terminal.

How the PIH Chain Works

The PIH field contains the Base64-encoded SHA-256 hash of the previous invoice's XML, after canonicalisation and before Base64 encoding of the submission. For the first ever invoice from a device, the PIH is set to a defined initial value specified in ZATCA's technical documentation.

ZATCA computes the hash of each accepted invoice and stores it as the new chain tip. When the next invoice arrives, ZATCA extracts the PIH field and compares it to the stored chain tip. If they match, the chain is intact. If they do not match, KSA-REJECT-02 is returned.

The PIH chain means you cannot delete, modify, or reorder previously submitted invoices without ZATCA detecting the change. It also means that a break in the chain — from any cause — stops all further submissions from that device until the chain is restored. Restoring a broken chain requires retrieving the correct chain tip from ZATCA's API and ensuring all subsequent invoices use it as their PIH.

Financial Penalties Under Article 49: The Real Cost of Rejection

Invoice rejections are not just an operational inconvenience — they have direct financial consequences under Article 49 of the VAT Implementing Regulations. Understanding the penalty schedule is the clearest way to quantify the risk of a non-certified or poorly integrated invoicing system. Read our full ZATCA penalties guide for the complete enforcement framework.

Violation First Offense Repeat (within 12 months) Maximum
Failure to issue a compliant e-invoice (including using a rejected invoice as a substitute) Up to 100% of the VAT due on that transaction Escalated per repeat occurrence — ZATCA discretion applies 100% of VAT per invoice, no stated cap
Failure to submit a B2C simplified invoice within the reporting window (before midnight of issuance date) SAR 1,000 – SAR 5,000 per invoice Up to SAR 50,000 cumulative within 12-month window SAR 50,000
Operating a non-ZATCA-approved invoicing system after wave deadline SAR 10,000 – SAR 50,000 Risk of business license suspension SAR 50,000 + license suspension
Failure to archive e-invoice records for the required retention period (6 years) SAR 5,000 – SAR 25,000 Escalated per audit finding SAR 25,000
Tampered or altered invoice records detected during audit Criminal referral risk + 100% of VAT due on affected invoices Criminal prosecution under Saudi tax law Unlimited — criminal jurisdiction applies

Put the penalty risk in perspective against software cost: the one-time license for StartPOS ZATCA Phase 2 Software starts at SAR 7,500. A single ZATCA enforcement action for operating a non-approved system starts at SAR 10,000. An audit finding involving multiple unsubmitted invoices can accumulate penalties well into six figures. The risk/cost arithmetic is straightforward.

These figures are based on Article 49 as published. Confirm current enforcement levels with a licensed Saudi tax advisor before making compliance decisions.

Industry-Specific Rejection Patterns

Different business sectors encounter different rejection patterns based on their invoice types, transaction mix, and operational environment. Here are the most common patterns we have seen across StartPOS deployments.

Retail POS and Convenience Stores

High-volume retail operations generate hundreds or thousands of B2C invoices per day. The most common rejection patterns are ICV sequence failures caused by concurrent terminal transactions and QR code encoding errors when item descriptions contain Arabic text. Retail businesses running multiple cashier terminals must implement a centralised ICV counter — never a per-terminal counter — to prevent sequence collisions. Arabic product names in TLV-encoded QR codes must be UTF-8 encoded correctly or they will trigger KSA-REJECT-08. For retail operations, the volume of B2C invoices means even a 0.1% rejection rate generates hundreds of non-compliant invoices per week.

Wholesale Distributors and B2B Operations

Wholesale businesses issue standard B2B invoices in clearance mode, which means every rejection immediately blocks a transaction. The most common patterns are KSA-REJECT-04 (TIN mismatch) when buyer VAT numbers are entered manually by sales staff with errors, BR-KSA-44 (credit note missing original UUID) when returns are processed days after the original transaction without retrieving the stored UUID, and KSA-REJECT-03 (signature failure) after CCSID certificate renewal if the new certificate is not deployed to all warehouse terminal devices. B2B rejections also affect the buyer's input VAT claims, creating commercial pressure that compounds the compliance risk.

Healthcare and Exempt VAT Categories

Clinics, pharmacies, and healthcare providers issue invoices that mix standard-rated services (15% VAT), zero-rated items (certain medications), and VAT-exempt medical services. Mixed-rate invoices are the primary rejection source: KSA-REJECT-10 (invalid VAT category code) occurs when exempt services are coded with the wrong category identifier, and KSA-REJECT-11 (line VAT inconsistency) occurs when a zero-rated line is given a non-zero VAT amount or an exempt line is given any VAT amount at all. Healthcare invoicing systems must implement ZATCA's full VAT category code list and validate each line item against the correct rate before submission.

Restaurants and Food Service

Restaurants operating with a split rate (15% dine-in, 5% tourism rate for eligible guests, or service charges treated differently from food) are a common source of BR-KSA-31 (VAT calculation mismatch). The 5% tourism VAT rate, where applicable, requires a separate VAT breakdown in the XML. Delivery integration — where orders come through aggregators like Jahez or HungerStation — can cause KSA-REJECT-06 (duplicate UUID) if the aggregator integration layer does not generate unique UUIDs per order. Restaurant POS systems with offline mode must ensure queued invoices are submitted before midnight to avoid KSA-REJECT-17 (window violation).

Multi-Branch Operations

Businesses with multiple branches across Saudi cities — whether in Riyadh, Jeddah, Dammam, or smaller markets — face a unique challenge: each branch, each POS terminal, and each EGS (Electronic Generation System) device requires its own CCSID certificate. A common failure mode is deploying the same CCSID certificate to multiple terminals at different branches, causing ICV conflicts (KSA-REJECT-05) and invalid signature errors (KSA-REJECT-03) as both terminals attempt to sign invoices with the same certificate in parallel. Every device must have its own unique CCSID certificate, onboarded individually through ZATCA's Fatoorah API.

Pre-Submission Checklist: 15 Checks Before Going Live

Before submitting your first production ZATCA Phase 2 invoice, verify all 15 of the following points. Every item on this list corresponds to a known rejection pattern. If any item cannot be confirmed, resolve it before switching from sandbox to production mode.

  1. Production CCSID certificate obtained and deployed. The production certificate has been issued via ZATCA's Fatoorah Onboarding API and is deployed to each device. Sandbox CSID is not being used against the production endpoint.
  2. CCSID TIN matches invoice seller TIN. The TIN registered during CCSID onboarding is identical to the VAT registration number being inserted in every invoice's SellerID field.
  3. Each device has a unique CCSID certificate. No two POS terminals or EGS devices share the same certificate. Confirmed per device.
  4. ICV counter is server-side with atomic increment. ICV management uses a database sequence with transactional locking. Counter does not increment on rejection. Counter does not increment before ZATCA acceptance is confirmed.
  5. PIH storage is persistent across restarts. The last accepted invoice hash is stored in a database and retrieved on application startup. In-memory caching is supplementary, not primary.
  6. XML validated against ZATCA SDK before every submission. Local schema validation runs on every invoice before calling the Fatoorah API. No invoice is submitted that has failed local validation.
  7. All mandatory UBL 2.1 KSA fields mapped. Every mandatory field in ZATCA's field list has a confirmed data source. No field is blank or carries a placeholder value.
  8. VAT calculation uses ZATCA rounding methodology. VAT is calculated per line, rounded to 2 decimal places per line, and summed. Invoice-level totals are not independently calculated.
  9. QR code encodes Arabic text as UTF-8. Seller name field in TLV encoding uses UTF-8 character set. QR code has been decoded and verified against a ZATCA QR decoder.
  10. UUID generation is RFC 4122 v4. UUIDs are generated at invoice creation time using a cryptographically random v4 UUID generator. UUID is stored per invoice for credit note reference retrieval.
  11. Timestamp synchronised to NTP. Server clock is NTP-synchronised. Timestamp format is ISO 8601 with UTC+3 offset. Drift monitoring is active.
  12. Invoice type codes are correct for each transaction type. Standard B2B invoice: type 388 with sub-type 01. Simplified B2C invoice: type 388 with sub-type 02. Credit note: type 381. Debit note: type 383.
  13. VAT category codes match line-item rates. Standard 15% rate uses category code S. Zero-rated uses Z. Exempt uses E. Out-of-scope uses O. Mixed-rate invoices carry separate VAT breakdown per category.
  14. Credit note workflow stores and retrieves original UUID. The original invoice UUID is stored at clearance time and retrievable by transaction reference. Credit note generation automatically populates BillingReference from the stored UUID.
  15. Submission timing respects the reporting window. B2C invoices are submitted before midnight KSA time on the day of issuance. Queue monitoring alerts when pending invoices risk missing the window.

Sandbox Testing Before Production Go-Live

ZATCA provides a sandbox environment — the Fatoorah Simulation Portal — that mirrors the production validation rules. Every integration must be tested in sandbox before production CCSID onboarding. Here is the recommended testing sequence:

  1. Obtain a compliance CSID by submitting a Certificate Signing Request (CSR) to ZATCA's Compliance CSID API (/compliance endpoint). The CSR must include your TIN, common name, serial number, and the required SANs (Subject Alternative Names) in the ZATCA-specified format.
  2. Run the ZATCA compliance test suite. Submit the 6 mandatory test invoices specified by ZATCA: a standard B2B invoice, a simplified B2C invoice, a credit note, a debit note, a zero-rated invoice, and an exempt invoice. Each must be accepted by the Compliance API before you can proceed.
  3. Obtain a production CCSID by calling ZATCA's Onboarding API (/production/csids) with your compliance CSID and OTP received by SMS to the registered mobile number on the ZATCA Fatoora portal.
  4. Test the hash chain with deliberate rejections. Intentionally trigger a KSA-REJECT-02 by submitting an invoice with a wrong PIH, then verify that your retry logic correctly recovers using the last accepted PIH without double-incrementing ICV.
  5. Test multi-terminal ICV concurrency. If deploying multiple terminals, simulate concurrent submissions and verify that your ICV counter prevents sequence conflicts under concurrent load.
  6. Validate QR code output using ZATCA's official QR decoder tool before going live. Confirm that decoded values match the invoice XML fields exactly, especially for Arabic seller names.

Do not go live on the production Fatoorah endpoint until all sandbox tests pass with zero rejection codes. Every rejection code that appears in sandbox testing is a rejection that will occur in production — the validation rules are identical.

How a ZATCA-Certified POS System Eliminates Rejection Risk

The twelve rejection causes above share a common thread: they are all systemic failures that a correctly engineered, ZATCA-certified invoicing system handles automatically. A business using StartPOS ZATCA Phase 2 Software does not encounter any of these rejection types in production, because the system eliminates them before they reach the Fatoorah API.

Here is how StartPOS handles each major rejection category:

  • Schema validation (KSA-REJECT-01, -09): Every invoice is validated against ZATCA's XSD and Schematron rules locally before submission. An invoice that would fail schema validation is flagged to the operator and never sent to the Fatoorah API.
  • Hash chain management (KSA-REJECT-02): PIH is stored in a redundant database with write confirmation before the next invoice is allowed. On startup, PIH is retrieved from the database and verified against ZATCA's API before the first submission of the session.
  • Certificate management (KSA-REJECT-03, -13, HTTP 401): CCSID certificate validity is monitored continuously. Automatic renewal alerts fire 30 days before expiry. Certificates are stored securely and deployed per-device.
  • ICV management (KSA-REJECT-05, -14): ICV uses a PostgreSQL sequence with serializable transaction isolation. ICV only increments after ZATCA returns an acceptance response. Rejections hold the current ICV for retry.
  • VAT calculation (BR-KSA-31): ZATCA's rounding methodology is hardcoded into the invoice calculation engine. The same calculation runs for all invoice types including mixed-rate invoices.
  • UUID generation (KSA-REJECT-06): UUIDs are generated using a cryptographically random v4 UUID library at invoice creation time and stored with the invoice record for credit note reference retrieval.
  • Credit note workflow (BR-KSA-44, KSA-REJECT-15): The credit note UI requires selecting an original cleared invoice. The original UUID is retrieved automatically from the stored transaction record.

The result is a 0% rejection rate across all StartPOS deployments in Saudi Arabia — a performance benchmark that no generic ERP integration, self-built XML generator, or uncertified POS system has matched in our experience. Compare this against the penalty exposure from ZATCA and the cost calculation is straightforward: a one-time license from SAR 7,500 against a minimum enforcement action of SAR 10,000 for a single non-compliance finding.

Ready to eliminate ZATCA invoice rejections permanently?

StartPOS is ZATCA Phase 2 certified with 0% rejection rate across all Saudi deployments. One-time license from SAR 7,500 (Starter) · SAR 10,500 (Advanced) · SAR 15,000 (AI Pro). Annual hosting SAR 1,200–2,400/year. No monthly fees. 15-day free trial, no card required.

Chat on WhatsApp: +966 50 197 1075 →

Businesses that have already deployed competing software and are experiencing rejections can also compare the specific capabilities that drive our 0% rejection rate against their current solution. See our StartPOS vs Rewaa comparison for a detailed technical feature breakdown.

Frequently Asked Questions

What does a ZATCA invoice rejection actually mean for my business?

A rejection means ZATCA's Fatoorah portal has refused to accept the submitted invoice and returned an error code. For B2B standard invoices in clearance mode, a rejected invoice cannot be legally delivered to the buyer — you must fix the error and resubmit before the transaction is complete. For B2C simplified invoices in reporting mode, the invoice may have already been delivered to the customer, but it is not ZATCA-compliant until successfully reported. Repeated rejections attract financial penalties under Article 49 of the VAT Implementing Regulations, starting at SAR 1,000 per invoice and escalating significantly for repeat violations.

What is error code KSA-REJECT-02 and how do I fix it?

KSA-REJECT-02 means the Previous Invoice Hash (PIH) field in your submitted invoice does not match the cryptographic hash of the last successfully accepted invoice in ZATCA's records. This breaks the invoice hash chain, which ZATCA uses as an anti-tampering mechanism. The fix requires your invoicing system to retrieve the hash of the last accepted invoice from your persistent storage, confirm it matches ZATCA's record, and insert it into the PIH field of the next invoice before signing. Common causes include server restarts that lose a cached hash without persisting it to a database, out-of-order submissions across multiple POS terminals, or a rejected invoice's hash being incorrectly stored as the chain tip. Remember: ZATCA does not advance the chain on rejection — the PIH for your retry should be the same PIH you used for the failed attempt.

What happens to the hash chain when an invoice is rejected?

When an invoice is rejected by ZATCA, the PIH chain does not advance — the rejected invoice's hash is not stored by ZATCA as the new chain tip. Your system must retry using the original PIH from the last successfully accepted invoice, not the hash of the rejected invoice. The ICV (Invoice Counter Value) also does not advance on a rejection: the same ICV number should be used on the corrected resubmission. If your software incorrectly increments the ICV on a rejection, you will face both KSA-REJECT-02 (PIH mismatch) and KSA-REJECT-05 (ICV out of sequence) errors simultaneously on the retry, compounding the problem.

How long does ZATCA give me to fix and resubmit a rejected invoice?

For B2C simplified invoices in reporting mode, ZATCA requires submission before midnight KSA time on the day of issuance. If a rejection occurs near midnight, you have very little time to diagnose and fix before the window closes. For B2B standard invoices in clearance mode, there is no formal deadline on the retry — but since the transaction cannot be completed until the invoice is cleared, the commercial pressure to resubmit immediately is significant. If a rejection causes a time gap in your submission log, document the sequence of events with timestamps and error codes. ZATCA may request this documentation during an audit to explain submission gaps.

Can I delete a rejected invoice and issue a new one with a different number?

No. Under ZATCA Phase 2, invoice sequence integrity is mandatory. You cannot delete a rejected invoice and start a fresh sequence. The correct approach is to fix the underlying error in the rejected invoice and resubmit it with the same ICV number and the correct PIH. If the error is unfixable (for example, the CSID certificate has expired and cannot be retroactively applied), you must contact ZATCA directly to handle the sequence gap formally. Never skip an ICV number and never issue two invoices with the same ICV — both trigger KSA-REJECT-05 errors and potential penalties for sequence tampering.

What is the penalty for a ZATCA invoice rejection in Saudi Arabia?

Under Article 49 of the VAT Implementing Regulations, penalties for non-compliant invoices begin at SAR 1,000 to SAR 5,000 per invoice for failure to submit within the required reporting window, escalating to SAR 50,000 cumulative within a 12-month period. Failure to issue a compliant e-invoice at all carries a penalty of up to 100% of the VAT amount due on that transaction. Operating a system that is not ZATCA-approved attracts penalties of SAR 10,000 to SAR 50,000 with risk of business license suspension. These figures should be confirmed with a licensed Saudi tax advisor as enforcement levels can be updated by ZATCA. See our full ZATCA penalties guide for the complete penalty schedule.

Does a ZATCA rejection affect my buyer's right to claim input VAT?

Yes. For B2B transactions, your buyer can only claim input VAT credit on invoices that have been successfully cleared by ZATCA's Fatoorah portal. A rejected or uncleared invoice does not carry a valid ZATCA clearance stamp, which means the buyer's VAT-registered accountant will reject it during input VAT reconciliation. This creates downstream commercial pressure on your business to resolve rejections immediately — not just for your own compliance, but to maintain good relations with B2B clients who depend on cleared invoices for their own VAT filings with ZATCA.

How does StartPOS achieve a 0% rejection rate across all Saudi deployments?

StartPOS implements every ZATCA Phase 2 technical requirement natively: server-side ICV counter with atomic increment using database sequences, persistent PIH chain storage with failover recovery and startup verification against the ZATCA API, full UBL 2.1 XML validation against ZATCA's SDK before every submission attempt, and automatic CCSID certificate renewal with 30-day advance warning. All submissions go through a pre-flight validation layer that replicates ZATCA's business rules locally — catching calculation errors, missing fields, QR code mismatches, and UUID collisions before they reach the Fatoorah API. Across all Saudi ZATCA Phase 2 deployments from production go-live, StartPOS has maintained a 0% rejection rate.

Conclusion

ZATCA invoice rejections follow predictable patterns. Every rejection code in the KSA-REJECT series and every BR-KSA business rule failure has a specific cause and a specific fix. The businesses that experience repeated rejections are almost always running software that was not designed specifically for ZATCA's technical requirements — generic ERP systems, self-built XML generators, or POS software that received a superficial ZATCA module bolted on without rigorous testing.

The two most impactful decisions a Saudi business can make to prevent rejections are: (1) choose a ZATCA-certified POS system that was built for ZATCA Phase 2 from the ground up, and (2) complete the full sandbox testing protocol before switching to production mode. Both decisions eliminate rejection risk at the source rather than managing it after the fact.

If you are currently receiving rejections or have not yet started your ZATCA Phase 2 integration, contact Gulf Union Ozone on WhatsApp at +966 50 197 1075 for a same-day diagnostic. We will identify the root cause of your rejections and outline the path to zero rejections — at no cost before you decide to proceed.