BR-KSA-31Third party flag is not 0 or 1 on a simplified invoice
Mutabiq checks Saudi ZATCA Phase 2 e-invoice XML before you submit it: pre-validation against published ZATCA requirements, not an approval by the authority. This page explains one rule, BR-KSA-31.
Five checks a month on the Free plan. The file is checked in memory and is never stored.
The message ZATCA prints
[BR-KSA-31]- For Simplified Tax Invoices and associated credit notes and debit notes (KSA-2, position 1 and 2 = 02), transaction types "self-billing" (KSA-2, position 7 = True) is not allowed.
Also cited in this report
BR-KSA-06
[BR-KSA-06]-The invoice transaction code (KSA-2) must exist and respect the following structure: NNPNESBCG where NN (positions 1 and 2) = invoice subtype: - 01 for tax invoice - 02 for simplified tax invoice P (position 3) = 3rd Party invoice transaction, 0 for false, 1 for true; N (position 4) = Nominal invoice transaction, 0 for false, 1 for true; E (position 5) = Exports invoice transaction, 0 for false, 1 for true; S (position 6) = Summary invoice transaction, 0 for false, 1 for true; B (position 7) = Self billed invoice transaction, 0 for false, 1 for true; C (position 8) = Continuous Supply invoice transaction, 0 for false, 1 for true; G (position 9) = B2G invoice transaction, 0 for false, 1 for true
What Mutabiq reports
One entry for each way this rule can be reported.
Reported as
What kind of value was found — empty, not_15_digits and the like — never the value itself.
Third party flag is not 0 or 1 on a simplified invoice
Reported asthird_party_flag_invalidthe third party flag is not 0 or 1
What is wrong
The invoice is a simplified invoice - the invoice transaction code (KSA-2) begins 02 - and position 3 of that code, the third party flag, holds something other than 0 or 1. ZATCA tests the five flag positions of a simplified invoice one at a time under BR-KSA-31 and rejects any that is not 0 or 1. The same character also fails BR-KSA-06, which applies to every invoice, so ZATCA reports this defect under two rules at once.
What to check in your ERP
The transaction code is seven characters written as text: 02 for a simplified invoice, then five flags each 0 or 1, with no separators, spaces or letters. A character outside that alphabet at position 3 usually means a free-text field is being mapped into the attribute, or the flags are being assembled from values that are not all set. A simplified invoice with no third party involved is 0200000.
Nominal supply flag is not 0 or 1 on a simplified invoice
Reported asnominal_flag_invalidthe nominal supply flag is not 0 or 1
What is wrong
The invoice is a simplified invoice - the invoice transaction code (KSA-2) begins 02 - and position 4 of that code, the nominal supply flag, holds something other than 0 or 1. ZATCA tests the five flag positions of a simplified invoice one at a time under BR-KSA-31 and rejects any that is not 0 or 1. The same character also fails BR-KSA-06, which applies to every invoice, so ZATCA reports this defect under two rules at once.
What to check in your ERP
The transaction code is seven characters written as text: 02 for a simplified invoice, then five flags each 0 or 1, with no separators, spaces or letters. A nominal supply is a supply made without consideration, and the flag is 1 only for that; an ordinary simplified sale is 0200000. A character outside 0 and 1 at position 4 usually means a lookup returned nothing and its result was written into the code unchecked.
A simplified invoice is marked as an export
Reported asexport_not_allowedmarked as an export where that is not allowed
What is wrong
The invoice is a simplified invoice - the invoice transaction code (KSA-2) begins 02 - and position 5 of that code, the exports flag, is not 0. Only rule packs before 2.0.0 report this: SDK 3.0.8's BR-KSA-31 required the exports flag on a simplified invoice to be 0. In SDK 3.4.8, which rule pack 2.0.0 reads, BR-KSA-31 accepts 0 or 1 at position 5 (KSA:2059-2060) and refuses only a self-billed simplified invoice (position 7), so a report produced under 2.0.0 never carries this note; a position 5 that is neither 0 nor 1 is reported as an invalid exports flag.
What to check in your ERP
A simplified invoice marked as an export is not refused under rule pack 2.0.0. If the sale is not an export, clear the flag all the same - a simplified invoice to a walk-in customer is 0200000 - and check which customer or destination setting drives position 5 of the code.
Summary invoice flag is not 0 or 1 on a simplified invoice
Reported assummary_flag_invalidthe summary invoice flag is not 0 or 1
What is wrong
The invoice is a simplified invoice - the invoice transaction code (KSA-2) begins 02 - and position 6 of that code, the summary invoice flag, holds something other than 0 or 1. ZATCA tests the five flag positions of a simplified invoice one at a time under BR-KSA-31 and rejects any that is not 0 or 1. The same character also fails BR-KSA-06, which applies to every invoice, so ZATCA reports this defect under two rules at once.
What to check in your ERP
The transaction code is seven characters written as text: 02 for a simplified invoice, then five flags each 0 or 1, with no separators, spaces or letters. The summary flag is 1 only where the document summarises several supplies over a period; an ordinary simplified sale is 0200000. A character outside 0 and 1 at position 6 usually means the flags are being built from a string of unequal length rather than positioned one by one.
A simplified invoice is marked as self-billed
Reported asself_billed_not_allowedmarked as self-billed where that is not allowed
What is wrong
The invoice is a simplified invoice - the invoice transaction code (KSA-2) begins 02 - and position 7 of that code, the self-billed flag, is not 0. ZATCA rejects that under BR-KSA-31: self-billing, where the customer raises the invoice on the supplier's behalf, is an arrangement between registered businesses and is not available on a simplified invoice. A separate rule, BR-KSA-07, forbids the same flag on an export invoice.
What to check in your ERP
The document type and the self-billing flag disagree. A self-billed invoice is issued as a standard tax invoice, so the transaction code begins 01 - for example 0100001. If this is an ordinary point-of-sale supply to a final consumer, clear the flag: a simplified invoice is 0200000. The flag is normally set from a self-billing agreement recorded against the customer, so check that the agreement is not being applied to documents outside it.
Exports flag in the transaction code is not 0 or 1
Reported asexport_flag_invalidthe exports flag is not 0 or 1
What is wrong
On a simplified invoice (the name attribute of cbc:InvoiceTypeCode starting 02), the fifth character of that attribute - the exports flag - is not 0 or 1. ZATCA rejects the document under BR-KSA-31, which requires positions 3 to 6 to be 0 or 1 and position 7, self-billing, to be 0. Earlier releases of ZATCA's checker refused the exports flag on a simplified invoice altogether; the current release accepts either value.
What to check in your ERP
Look at how the seven-character transaction code is built. Each flag position must be exactly 0 or 1; a space, a letter or a missing character in position 5 usually comes from a code padded or cut to the wrong length.
The clause that runs
Quoted from the validation-rule stylesheet ZATCA publishes, at the file and line named below. The executed guard is what the check runs; the reported test is what it prints when it fails, and the two are not always the same.
Executed guard
not( (substring(./@name, 3,1) = '1' or substring(./@name, 3,1) = '0') and (substring(./@name, 4,1) = '1' or substring(./@name, 4,1) = '0') and (substring(./@name, 5,1) = '1' or substring(./@name, 5,1) = '0') and (substring(./@name, 6,1) = '1' or substring(./@name, 6,1) = '0') and (substring(./@name, 7,1) = '0'))
Reported test
(substring(./@name, 3,1) = '1' or substring(./@name, 3,1) = '0') and (substring(./@name, 4,1) = '1' or substring(./@name, 4,1) = '0') and (substring(./@name, 5,1) = '0') and (substring(./@name, 6,1) = '1' or substring(./@name, 6,1) = '0') and (substring(./@name, 7,1) = '0')
As shipped in ZATCA SDK 3.4.8: the copy quoted here is, byte for byte, the file that release ships. The date in the file name is the name ZATCA gives the file; the rules in it are those of SDK 3.4.8.
A worked example
A synthetic document from the measured test corpus that trips this rule, shown where it differs from one that passed. Mutabiq's report names the class of the value, never the value itself.
Where it differs from a document that passed
− This example
+ A document that passed
<cbc:IssueDate>2026-09-01</cbc:IssueDate><cbc:IssueTime>10:00:00</cbc:IssueTime>−This example: <cbc:InvoiceTypeCode name="020000">388</cbc:InvoiceTypeCode>+A document that passed: <cbc:InvoiceTypeCode name="0200000">388</cbc:InvoiceTypeCode><cbc:DocumentCurrencyCode>SAR</cbc:DocumentCurrencyCode><cbc:TaxCurrencyCode>SAR</cbc:TaxCurrencyCode>⋯</cac:AccountingCustomerParty><cac:Delivery>−This example: <cbc:ActualDeliveryDate>2026-09-01Z</cbc:ActualDeliveryDate>+A document that passed: <cbc:ActualDeliveryDate>2026-09-01</cbc:ActualDeliveryDate></cac:Delivery><cac:PaymentMeans>
Document
bad-52-simplified-short-name-ungated.xml
Mutabiq's verdict
Not passed
Reported as
self_billed_not_allowedmarked as self-billed where that is not allowed