BR-KSA-CL-03An attachment does not declare its media type

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-CL-03.

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-CL-03]-Mime code must be according to subset of IANA code list.

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.

An attachment does not declare its media type

Reported asmime_code_missingno media type declared

What is wrong

An attachment payload in this document carries no mimeCode attribute, or one whose value is empty or nothing but whitespace. ZATCA refuses the document under BR-KSA-CL-03. This is worth stating plainly because the schema will not catch it for you: mimeCode is an optional attribute in UBL, so a document without it is perfectly valid against the schema and is still refused on this clause alone. BR-KSA-CL-03 asks that every attachment payload in the document - cac:AdditionalDocumentReference/cac:Attachment/cbc:EmbeddedDocumentBinaryObject - declare its media type in the mimeCode attribute, and that the value be one of ZATCA's subset of the IANA list: text/csv, text/plain, application/pdf, image/png, image/jpeg, image/tiff, application/acad, application/dwg, drawing/dwg, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet and application/vnd.oasis.opendocument.spreadsheet. The value is compared after leading and trailing whitespace is normalised away and is otherwise exact and case-sensitive, so TEXT/PLAIN is not text/plain. Two things about where this fires. It judges every such block anywhere in the document, including one nested inside a credit note's billing reference, and it stops at the first that fails, so others may be affected too. And a ZATCA invoice carries at least two of these blocks that are not attachments in the ordinary sense - the previous invoice hash (PIH) and the QR code, both of which must be declared text/plain - so this note points at one of those far more often than at a document a user attached.

What to check in your ERP

Start with the PIH and QR blocks rather than with user attachments: both must carry mimeCode="text/plain", and a template that writes the element without the attribute is the most common cause of this note. For genuine attachments, the usual cause is a document store that keeps the file's bytes and its name but not its media type, so the export has nothing to write; deriving the value from the file extension at export time is an acceptable fix as long as it is mapped onto ZATCA's eleven values and not passed through raw.

An attachment's media type is not one ZATCA accepts

Reported asnot_in_iana_subseta media type ZATCA does not accept

What is wrong

An attachment payload in this document declares a mimeCode that is not on ZATCA's list, and ZATCA refuses the document under BR-KSA-CL-03. A value carrying a space inside it fails as well, for the same reason: no member of the list contains one. BR-KSA-CL-03 asks that every attachment payload in the document - cac:AdditionalDocumentReference/cac:Attachment/cbc:EmbeddedDocumentBinaryObject - declare its media type in the mimeCode attribute, and that the value be one of ZATCA's subset of the IANA list: text/csv, text/plain, application/pdf, image/png, image/jpeg, image/tiff, application/acad, application/dwg, drawing/dwg, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet and application/vnd.oasis.opendocument.spreadsheet. The value is compared after leading and trailing whitespace is normalised away and is otherwise exact and case-sensitive, so TEXT/PLAIN is not text/plain. Two things about where this fires. It judges every such block anywhere in the document, including one nested inside a credit note's billing reference, and it stops at the first that fails, so others may be affected too. And a ZATCA invoice carries at least two of these blocks that are not attachments in the ordinary sense - the previous invoice hash (PIH) and the QR code, both of which must be declared text/plain - so this note points at one of those far more often than at a document a user attached.

What to check in your ERP

Check the PIH and QR blocks first: both must be text/plain, and values such as application/octet-stream, base64Binary, text/xml and application/xml turn up there when a template was written by analogy with the payload's base64 encoding rather than from the standard. For genuine attachments the common causes are a media type read from the operating system or from an upload header and passed straight through, image/jpg where the registered type is image/jpeg, a type with parameters appended such as text/plain followed by a charset, and a value upper-cased by a formatting step. Map onto the eleven accepted values explicitly, and refuse the attachment in your own system if its type is not among them, because ZATCA will refuse the whole invoice for it.

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(((not(contains(normalize-space(@mimeCode), ' ')) and contains(' text/csv text/plain application/pdf image/png image/jpeg image/tiff application/acad application/dwg drawing/dwg application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/vnd.oasis.opendocument.spreadsheet ', concat(' ', normalize-space(@mimeCode), ' ')))))

Reported test

((not(contains(normalize-space(@mimeCode), ' ')) and contains(' text/csv text/plain application/pdf image/png image/jpeg image/tiff application/acad application/dwg drawing/dwg application/vnd.openxmlformats-officedocument.spreadsheetml.sheet application/vnd.oasis.opendocument.spreadsheet ', concat(' ', normalize-space(@mimeCode), ' '))))
Evaluated against
cac:AdditionalDocumentReference/cac:Attachment/cbc:EmbeddedDocumentBinaryObject
Source
vendor/zatca/schematron/20210819_ZATCA_E-invoice_Validation_Rules.xsl:2504

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:ID>PIH</cbc:ID>  <cac:Attachment>This example:     <cbc:EmbeddedDocumentBinaryObject mimeCode="application/octet-stream">NWZlY2ViNjZmZmM4NmYzOGQ5NTI3ODZjNmQ2OTZjNzljMmRiYzIzOWRkNGU5MWI0N… (full length: 197)A document that passed:     <cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain">QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUF… (full length: 375)  </cac:Attachment></cac:AdditionalDocumentReference>
Document
bad-42-pih-wrong-mimecode.xml
Mutabiq's verdict
Not passed
Reported as
not_in_iana_subseta media type ZATCA does not accept

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.

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.