BR-KSA-06Invoice transaction code is not written on the invoice type element

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-06.

Validate 5 invoices free

Five checks a month on the Free plan. The file is checked in memory and is never stored.

The message ZATCA prints

[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.

Invoice transaction code is not written on the invoice type element

Reported asinvoice_type_name.name_missingthe name attribute is missing

What is wrong

The invoice type element is present but has no name attribute, or carries one that is empty. That attribute on cbc:InvoiceTypeCode is the KSA-2 field: it carries the invoice transaction type - standard or simplified - together with five flags: third party, nominal, exports, summary and self-billed. ZATCA reads an absent attribute as an empty string, which is neither 01 nor 02, so the invoice is rejected under BR-KSA-06; an attribute written with an empty value fails at the same step of the same test. A document with no cbc:InvoiceTypeCode element at all is a different defect and is reported separately, under BR-04.

What to check in your ERP

The element itself is already being written, so the document type is reaching the export and only the attribute beside it is not. In your e-invoicing settings, check that the invoice transaction type is configured and that the mapping writes it into the name attribute of cbc:InvoiceTypeCode rather than into a field of its own. It is a seven character code such as 0100000: the first two characters are 01 for a standard tax invoice or 02 for a simplified one, and the remaining five are flags valued 0 or 1. An attribute written with an empty value fails exactly as one that was never written, so check the value the mapping produces and not only that it produces the attribute.

Invoice transaction code is too short

Reported asinvoice_type_name.too_shortshorter than required

What is wrong

The name attribute on cbc:InvoiceTypeCode, the KSA-2 field, is shorter than seven characters. ZATCA tests positions 1 to 7 one position at a time, so a code that stops early fails at the first missing position, under BR-KSA-06.

What to check in your ERP

The code is seven characters and its zeros are significant: 01 or 01000 is not the same value as 0100000. Check whether the export is trimming the value, or whether the flags are held as a number somewhere and the zeros are lost on the way out. Write it as text, seven characters, for example 0100000.

Invoice transaction code is not in the expected format

Reported asinvoice_type_name.bad_patternnot in the expected format

What is wrong

The name attribute on cbc:InvoiceTypeCode, the KSA-2 field, is long enough, but one of its first seven positions holds something ZATCA does not accept, under BR-KSA-06. Positions 1 and 2 must be 01 for a standard tax invoice or 02 for a simplified one, and positions 3 to 7 must each be 0 or 1.

What to check in your ERP

Check the transaction type configured for this document. The five flags after the type are, in order: third party, nominal, exports, summary and self-billed, each 0 or 1, with no separators, spaces or letters. A value of 0200000, for instance, is a simplified invoice. A character outside that alphabet usually means a free-text field is being mapped into this attribute.

Invoice transaction code is too long for an export invoice

Reported asinvoice_type_name.too_long_exporttoo long for an export invoice

What is wrong

The name attribute on cbc:InvoiceTypeCode, the KSA-2 field, is longer than seven characters and its exports flag, position 5, is set to 1. On an export invoice ZATCA applies a seven character ceiling to this field and rejects anything longer, under BR-KSA-CL-0222 - the rule whose own message text calls it BR-KSA-02.

What to check in your ERP

Trim the code to exactly seven characters, for example 0100100. The extra characters usually come from padding the field to a fixed width, an appended suffix, or trailing whitespace picked up from a configuration table. Confirm as well that the exports flag is meant to be 1 for this document: it belongs only on an invoice to a customer outside the Kingdom.

Invoice transaction code is longer than seven characters

Reported asinvoice_type_name.too_longlonger than allowed

What is wrong

The name attribute on cbc:InvoiceTypeCode, the KSA-2 field, is longer than the seven positions ZATCA specifies for it. The ZATCA checks read the first seven positions and, on an invoice like this one, do not object to the extra characters - so this is reported as a risk rather than as a rejection. On an export invoice the same value would be rejected.

What to check in your ERP

Trim the code to exactly seven characters, for example 0100000. The extra characters usually come from padding the field to a fixed width, an appended suffix, or trailing whitespace picked up from a configuration table. Fixing it now also protects the same export path if the exports flag is ever set on a future invoice.

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( ( ( (string-length(@name) = 7 and (substring(@name,1,2) = '01' or substring(@name,1,2) = '02') and (substring(@name,3,1) = '0' or substring(@name,3,1) = '1') and (substring(@name,4,1) = '0' or substring(@name,4,1) = '1') and (substring(@name,5,1) = '0' or substring(@name,5,1) = '1') and (substring(@name,6,1) = '0' or substring(@name,6,1) = '1') and (substring(@name,7,1) = '0' or substring(@name,7,1) = '1') ) or (string-length(@name) = 9 and (substring(@name,1,2) = '01' or substring(@name,1,2) = '02') and (substring(@name,3,1) = '0' or substring(@name,3,1) = '1') and (substring(@name,4,1) = '0' or substring(@name,4,1) = '1') and (substring(@name,5,1) = '0' or substring(@name,5,1) = '1') and (substring(@name,6,1) = '0' or substring(@name,6,1) = '1') and (substring(@name,7,1) = '0' or substring(@name,7,1) = '1') and (substring(@name,8,1) = '0' or substring(@name,8,1) = '1') and (substring(@name,9,1) = '0' or substring(@name,9,1) = '1') ) or (string-length(@name) = 8 and (substring(@name,1,2) = '01' or substring(@name,1,2) = '02') and (substring(@name,3,1) = '0' or substring(@name,3,1) = '1') and (substring(@name,4,1) = '0' or substring(@name,4,1) = '1') and (substring(@name,5,1) = '0' or substring(@name,5,1) = '1') and (substring(@name,6,1) = '0' or substring(@name,6,1) = '1') and (substring(@name,7,1) = '0' or substring(@name,7,1) = '1') and (substring(@name,8,1) = '0' or substring(@name,8,1) = '1') ) ) ) )

Reported test

((string-length(@name))= 7) and ((substring(@name,1,2) = '01') or (substring(@name,1,2) = '02')) and ((substring(@name,3,1) = '0') or (substring(@name,3,1) = '1')) and ((substring(@name,4,1) = '0') or (substring(@name,4,1) = '1')) and ((substring(@name,5,1) = '0') or (substring(@name,5,1) = '1')) and ((substring(@name,6,1) = '0') or (substring(@name,6,1) = '1')) and ((substring(@name,7,1) = '0') or (substring(@name,7,1) = '1'))
Evaluated against
cbc:InvoiceTypeCode
Source
vendor/zatca/schematron/20210819_ZATCA_E-invoice_Validation_Rules.xsl:905

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="010000">388</cbc:InvoiceTypeCode>A document that passed: <cbc:InvoiceTypeCode name="0100000"> 388 </cbc:InvoiceTypeCode><cbc:DocumentCurrencyCode>SAR</cbc:DocumentCurrencyCode><cbc:TaxCurrencyCode>SAR</cbc:TaxCurrencyCode>
Document
bad-01-wrong-type-name.xml
Mutabiq's verdict
Not passed
Reported as
too_shortshorter than required

Download this example (.xml)Check it in Mutabiq

This page's example, checked by the same rules your own upload goes through. No upload and no sign-in.

ERP guides

Product names identify the systems only. Mutabiq is independent of their vendors and is not affiliated with or endorsed by any of them.

Rules evaluated against the same part of the document. One wrong value often reports several of them at once.

Check an invoice

Check your own invoice

© 2026 Hayatiq AI Solutions F.Z.E. All rights reserved.