Guide · Saudi Arabia
ZATCA Phase 2 rejection errors and how to fix them
The validation errors and warnings a POS or accounting integration meets most often, each with its code, what it checks, the usual cause and the fix.
Errors, warnings and what ZATCA does with each
ZATCA answers every submitted document with one of three outcomes. Accepted comes back as HTTP 200. Accepted with warnings comes back as HTTP 202. Rejected comes back as HTTP 400, and it takes one error to get there: ZATCA says a document with even one error is rejected entirely.
Warnings are different. ZATCA says they are temporarily accepted and might become rejections in the future, that continuous warnings are investigated, and that repeated non-compliance that results in warnings may be subject to applicable penalties. Do not resubmit an invoice that came back with warnings. Fix the cause so the next ones come back clean.
The tables below cover the codes a POS or accounting integration meets most often. The full list in the XML standard is longer. The rule texts come from ZATCA's XML Implementation Standard, version 1.2. Rows marked “SDK only” come from ZATCA's validation SDK, which has rules the standard does not. Whether a code is an error or a warning is as classified at the time of writing (SDK version 238-R3.4.8). ZATCA changes this between SDK versions: BR-KSA-08 and BR-KSA-F-01, for example, were classified differently in an older copy. Check against the SDK you test with before you rely on a row.
Errors: the invoice is rejected
| Code | What it checks | Typical cause in a POS integration | Fix |
|---|---|---|---|
| BR-KSA-03 | The document has a UUID (KSA-1) made of letters, digits and dashes only. | The UUID is missing, or a Windows GUID formatter left braces around it. | Generate a UUID for every document and strip the braces. |
| BR-KSA-04 | The issue date (BT-2) is not later than the current date. | The server clock or time zone is wrong, or the invoice is future-dated. | Sync the clock with NTP and handle time zones: issue time is Saudi time, or UTC with a "Z". |
| BR-KSA-05BR-04 | The invoice type code is present and comes from ZATCA’s list: 388 invoice, 381 credit note, 383 debit note, 386 prepayment. | The POS’s own document types are sent across without mapping. | Map every POS document type to a code on ZATCA’s list. |
| BR-KSA-06 | The transaction code (KSA-2) follows ZATCA’s flag structure: it starts with 01 for a tax invoice and 02 for a simplified one. | The flag string is missing or malformed. | Build it as the XML standard describes, starting with 01 for standard invoices and 02 for simplified. |
| BR-KSA-14 | If a buyer ID (BT-46) is sent, it uses one of the allowed schemes (TIN, CRN, MOM, MLS, 700, SAG, NAT, GCC, IQA, PAS, OTH) and contains letters and digits only. | The buyer ID is sent with no scheme, a scheme that is not on the list, or with spaces or dashes. | Map each customer ID type to one of the allowed scheme codes and strip non-alphanumeric characters. |
| BR-KSA-17 | Credit and debit notes (381 and 383) carry a reason (KSA-10). | A refund or void is sent without a reason. | Make the reason mandatory on returns and refunds, and map it to KSA-10. |
| BR-KSA-18 | The VAT category code is one of S, Z, E or O. | Custom tax codes such as “VAT15” are sent as they are. | Map the tax table to S, Z, E or O. |
| BR-KSA-33BR-KSA-34 | The invoice counter value (KSA-16) exists and contains digits only. | The counter is missing, or a branch code is prefixed to it. | Keep a purely numeric counter for each unit. |
| BR-KSA-39 | The seller VAT number (BT-31) is present. | The seller profile was never configured. | Set the seller VAT number in the integration config. |
| BR-KSA-40BR-KSA-44 | The seller VAT number, and the buyer’s if present, has 15 digits and starts and ends with 3. | A typo, stray spaces, or a 10-digit TIN used instead. | Validate the format at setup and when a customer is created. |
| BR-KSA-52BR-KSA-53 | The line VAT amount (KSA-11) and the line amount with VAT (KSA-12) are present on tax invoices (01). | Totals are only worked out at document level. | Send a TaxTotal with TaxAmount and RoundingAmount on every line. |
| BR-KSA-68BR-KSA-EN16931-02 | The tax currency code (BT-6) exists and equals SAR. | The field is left out, or a foreign-currency invoice sends USD as the tax currency. | Send cbc:TaxCurrencyCode as SAR on every invoice and convert the VAT amount into BT-111. |
| BR-KSA-70 | The issue time (KSA-25) is present as hh:mm:ss, or hh:mm:ssZ for UTC. | The time is missing, or it carries milliseconds or an offset. | Format the time exactly as the rule says. |
| BR-KSA-84SDK only | Standard-rated VAT rates are limited to 5 or 15. | The rate is sent as 0.15, or an out-of-date rate is used. | Send the rate as a percentage number such as 15. |
| BR-KSA-DEC-02 | VAT rates are between 0.00 and 100.00, with at most two decimals and no “%” sign. | A text value such as “15%”, or 15.000. | Send a number with at most two decimals. |
| BR-KSA-F-01 | Dates are formatted YYYY-MM-DD. | A local date format such as 24/10/2026, or a Hijri date. | Use ISO 8601 dates.An older SDK copy classified this as a warning. |
| BR-KSA-F-04 | Document amounts and quantities are positive, unless the rule says otherwise. | Returns are sent as invoices with negative quantities. | Issue a credit note (381) with positive amounts instead of negative lines. |
| BR-CO-14BR-CO-15 | Total VAT (BT-110) equals the sum of the VAT category amounts (BT-117), and total with VAT (BT-112) equals total without VAT (BT-109) plus total VAT (BT-110). | Rounding per line gives a halala of difference against rounding per category, or VAT-inclusive POS prices are back-calculated with inconsistent rounding. | Compute BT-110 as the sum of the BT-117 amounts and derive the other totals from the same rounded values. |
| BR-CUSTOM-VALIDATION-01SDK only | The seller VAT number differs from the buyer VAT number. | The seller’s own VAT number is used as a placeholder for the buyer. | Leave the buyer VAT number empty and use BT-46 if you need an ID. |
Warnings: the invoice is accepted
| Code | What it checks | Typical cause in a POS integration | Fix |
|---|---|---|---|
| BR-KSA-98SDK only | A simplified invoice is submitted within 24 hours of issue. | An offline POS queue, or a nightly batch job. | Report continuously and retry. If an outage stops you, ZATCA has a failure-notification form. |
| BR-KSA-61 | The previous invoice hash (KSA-13) exists. | The PIH field is empty. | Store the last hash for each unit and send it with every document. |
| BR-KSA-26 | The PIH is a base64 SHA-256 hash computed with ZATCA’s defined transform. For the first document it is the hash of “0”. | Wrong canonicalisation, or hashing the signed XML. | Follow the transform steps in the XML standard (BR-KSA-26) and the technical guidelines. |
| BR-KSA-27 | The document has a QR code (KSA-14) as base64Binary. | The QR code is not embedded in the XML. | Embed it as an AdditionalDocumentReference with the ID QR. |
| BR-KSA-60 | A cryptographic stamp exists on simplified documents (02). | The POS sends simplified invoices unsigned and expects ZATCA to stamp them. | Sign them on your own unit. ZATCA does not stamp simplified invoices. |
| BR-KSA-08 | The seller ID (BT-29) appears once, with an allowed scheme (CRN, MOM, MLS, SAG, OTH or 700), alphanumeric. | No commercial registration number in the seller profile, or several IDs. | Add the branch’s commercial registration number.The classification differed between SDK versions. |
| BR-KSA-09 | The seller address has street, building number, postal code, city, district and country. | An incomplete Saudi National Address. | Complete the National Address in the configuration. |
| BR-KSA-42BR-KSA-81 | The buyer name (BT-44) is present on tax invoices, and another buyer ID (BT-46) is present when the buyer VAT number is absent. | A business sale is rung up as a walk-in customer, or a business customer has no VAT number and no registration number. | Require a customer on business sales and capture the registration number or ID. |
| BR-KSA-56 | Credit and debit notes carry the billing reference ID (BT-25) of the original invoice. | A refund is not linked to the original sale. | Store the original invoice number and send it. |
| BR-KSA-23BR-KSA-24BR-KSA-69BR-KSA-CL-04BR-KSA-83 | Each VAT breakdown for exempt (E), not-subject (O) or zero-rated (Z) amounts carries a ZATCA exemption or exception reason code and text. | Zero-rated items are set up with no reason. | Map the items to the VATEX-SA reason codes in the XML standard. |
| BR-KSA-51 | The line amount with VAT (KSA-12) equals the line net (BT-131) plus the line VAT (KSA-11). | Rounding is done per unit instead of per line. | Round per line, the same way every time. |
| BR-KSA-85BR-KSA-86SDK only | The buyer phone number and email address have a valid format, if present. | A phone number sent with spaces or dashes. | Normalise the format, or leave the field out. |
Failures that have no published code
Some failures come from the API itself. We found no ZATCA-published list of those response codes, so we do not list any. The mechanisms behind them are documented, and they are where live integrations tend to break.
- Hash chain. Each document carries the hash of the document generated immediately before it. That has to be the last document generated, even if ZATCA rejected it, because the platform records the hash of rejected submissions. ZATCA’s example says to use the rejected document’s hash, not the hash of the document before it.
- Counter reuse. ZATCA says once a document is generated with an invoice counter value, that value cannot be mentioned on another document. A corrected or rebuilt document has to take a new counter value. Resending the identical document after a 429 or 5xx response is not a new document, so it keeps its own values.
- Certificates. ZATCA says invoices signed with invalid certificates are rejected. HTTP 401 means to check the authentication certificate and secret and resubmit. Compliance checks fail on a missing, invalid or expired compliance CSID.
- Onboarding. A CSR can be rejected for an invalid or expired OTP, an OTP that does not match the VAT number, an invalid VAT number, or a missing field. A business that has just registered for VAT waits two business days before it can onboard, and invoices issued to it are rejected until then.
What to do with a rejected document
Treat the fix as a new document: a new UUID, a new counter value and a new hash, with its PIH set to the hash of the document generated immediately before it.
- A standard (B2B) invoice is not valid until it is cleared. Correct it and submit it again, with the invoice date updated.
- A simplified (B2C) receipt is already with the customer. Do not reissue it. Correct the data and report it as a new document, with the date of the original transaction. ZATCA’s guideline also contains an FAQ that says to cancel with a credit note and issue a new invoice, so ask your accountant which route applies.
- Retry on HTTP 429, 500, 503 and 504, which ZATCA marks as please resend. Do not retry a 400 unchanged.
- Test before you submit. ZATCA’s SDK validates XML and QR codes offline, and its sandbox simulates onboarding and submission.
For who has to integrate, the clearance and reporting routes, and how a cloud POS is connected in the first place, read the ZATCA Phase 2 integration guide.
Common questions
Sources
Every code and quote on this page comes from the ZATCA documents below, as checked on 24 October 2026. Severities were read from a copy of SDK 238-R3.4.8, because the SDK file sits behind a ZATCA sign-in; confirm them against a fresh download. Causes and fixes are our own engineering notes.
- XML Implementation Standard (version 1.2, 19 May 2023), section 13, validation rules
- ZATCA SDK (Compliance and Enablement Toolbox) download page
- Detailed Guidelines for E-Invoicing (version 2, May 2023)
- E-invoicing Detailed Technical Guidelines (version 2, November 2022)
- Security Features Implementation Standards (version 1.2, 19 May 2023)
- E-Invoicing Implementation Resolution: controls, requirements, technical specifications and procedural rules (unofficial English translation)
Find out why your invoices keep coming back.
Start with a 30-minute audit. We look at what your system sends to ZATCA and where it differs from the rules, whether or not you hire us.