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

ZATCA validation errors as classified in SDK version 238-R3.4.8
CodeWhat it checksTypical cause in a POS integrationFix
BR-KSA-03The 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-04The 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-04The 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-06The 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-14If 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-17Credit 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-18The 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-34The 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-39The 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-44The 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-53The 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-02The 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-70The 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 onlyStandard-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-02VAT 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-01Dates 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-04Document 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-15Total 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 onlyThe 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

ZATCA validation warnings as classified in SDK version 238-R3.4.8
CodeWhat it checksTypical cause in a POS integrationFix
BR-KSA-98SDK onlyA 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-61The 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-26The 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-27The 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-60A 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-08The 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-09The 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-81The 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-56Credit 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-83Each 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-51The 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 onlyThe 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

No. A response with warnings (HTTP 202) means ZATCA accepted the invoice. Fix the cause in your system so the next invoices come back clean. ZATCA says warnings are accepted for now and might become rejections in the future, and that continuous warnings are investigated.
It is not valid until ZATCA clears it. Correct it and submit it again as a new document with its own UUID, counter value and hash. ZATCA says the date on the invoice should be updated.
Do not reissue the receipt to the customer. Correct the data and report it as a new document, keeping the date of the original transaction. Another FAQ in the same ZATCA guideline says an invoice that was not reported should be cancelled with a credit note and replaced, so ask your accountant which route applies to you.
No. ZATCA says it considers an invoice once, based on identifiers such as the UUID and the hash. Gaps in the invoice sequence are a different matter: ZATCA says they are subject to further investigation and may result in penalties.

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.

WhatsAppBook a free audit