Skip to content

BR-04: Add the invoice type code

The document has no cbc:InvoiceTypeCode (cbc:CreditNoteTypeCode in a credit note), or it is blank. Add the code for what the document is, such as 380.

EN 16931Fatal: the document is invalidCore fields

The short answer

BR-04 fails when the document root has no type code with a value: no cbc:InvoiceTypeCode in an Invoice, no cbc:CreditNoteTypeCode in a CreditNote, or one that is empty. Add the element with the code for the kind of document you are sending, 380 for a commercial invoice or 381 for a credit note.

The UBL schema treats the type code as optional, so the XSD layer passes without it and this EN 16931 rule is the first to object.

What the rule checks

The rule runs once per document, on the root. It passes when either type code element directly under the root has text other than whitespace.

An absent element gives BR-04 alone, as in the recorded example, because the code list rules have no element to test. An empty or whitespace-only element gave four findings when tried: BR-04, BR-CL-01, the Peppol type code rule for that root (PEPPOL-EN16931-P0100 or PEPPOL-EN16931-P0101) and PEPPOL-EN16931-R008.

The rule does not judge the value. Any non-blank text satisfies it; whether the code is permitted is for BR-CL-01 and the Peppol profile rules to decide.

TermMeaningUBL element
BT-3Invoice type codecbc:InvoiceTypeCode (cbc:CreditNoteTypeCode in a credit note)

How an integration ends up here

Possible causes, from the shape of the rule rather than from measured usage:

  • The mapping was built for a format where the message type implies the document type, and nothing sets the UBL element.
  • The type code is filled from a configuration value that is missing in this environment, and the serialiser drops the element.
  • A credit note template was derived from the invoice template, and the invoice type code line was deleted without adding cbc:CreditNoteTypeCode in its place.

How to fix it

  1. Decide what the document is in business terms, and choose the code from the Peppol list for that root element: 380 for an ordinary invoice, 381 for an ordinary credit note.
  2. Emit cbc:InvoiceTypeCode in its schema position: after cbc:IssueDate and cbc:DueDate, before any cbc:Note, cbc:TaxPointDate and cbc:DocumentCurrencyCode. Placed after cbc:DocumentCurrencyCode, it failed the XSD layer when tried.
  3. For a CreditNote, emit cbc:CreditNoteTypeCode instead; the invoice element name is not valid there.
  4. Make the code a required output of the mapping, so a missing value stops the export instead of silently dropping the element.

Validate your corrected invoice

Before and after

These are fragments, not complete documents. The complete synthetic documents they come from are linked below.

Fragment of the failing invoice: the header goes from the due date straight to the currency

<cbc:IssueDate>2026-09-08</cbc:IssueDate>
<cbc:DueDate>2026-10-08</cbc:DueDate>
<!-- no cbc:InvoiceTypeCode in the failing document -->
<cbc:DocumentCurrencyCode>GBP</cbc:DocumentCurrencyCode>

Fragment of the corrected invoice: 380, commercial invoice, between the due date and the currency

<cbc:IssueDate>2026-09-08</cbc:IssueDate>
<cbc:DueDate>2026-10-08</cbc:DueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
<cbc:DocumentCurrencyCode>GBP</cbc:DocumentCurrencyCode>

The corrected invoice has <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode> between the due date and the currency code; the failing invoice has no type code element at all. The failing document reports only BR-04. With no element present, neither BR-CL-01 nor PEPPOL-EN16931-P0100 has a value to check, so the Peppol layer passes.

What the validator reported

Recorded on phive 12.1.0 / phive-rules-peppol 4.5.6 / Saxon-HE 12.10, the engine behind the free validator, using synthetic data. A recorded result is regression evidence for these documents; it is not a certification.

Where it applies

  • Applies to UBL Invoice and CreditNote. A credit note without cbc:CreditNoteTypeCode reported this rule when tried, and it too passed the XSD layer.
  • The finding comes from the EN 16931 layer. Peppol has no presence rule of its own for the type code.
  • Once the element is present, its value is checked by BR-CL-01 against the EN 16931 list and by PEPPOL-EN16931-P0100 or PEPPOL-EN16931-P0101 against the narrower Peppol list.

Scope and source

Written for Peppol BIS Billing 3.0.21 (May 2026), EN 16931 1.3.16, as applied to UBL 2.1 Invoice and CreditNote documents. Other profiles, syntaxes and releases can define this identifier differently. Guidance version 2026-09-24.1: source checked 2026-09-24, explanation last updated 2026-09-24.

The official definition of BR-04 carries the normative wording and test. This page is our explanation of it, not a copy.

Guidance does not change the engine verdict. Fixing this finding does not mean the document passes every layer, and validation does not certify legal or tax compliance or transmit a document over Peppol.