The short answer
BR-CL-18 fails when the cbc:ID in a line item's cac:ClassifiedTaxCategory is outside the permitted VAT category codes. Replace it with the code for the category the line was really taxed in; in the recorded example the line says SR and the Standard rated code is S.
While the line carries an unrecognised code it belongs to no category, so the breakdown that should total it no longer matches and the category rules report that too.
What the rule checks
The rule runs on every cbc:ID inside a cac:ClassifiedTaxCategory, which in these documents is the item of each cac:InvoiceLine or cac:CreditNoteLine. Breakdowns and document-level allowances and charges fall under BR-CL-17 instead.
It accepts the same ten codes as the breakdown rule: S, Z, E, AE, K, G, O, L, M and B. Surrounding spaces are trimmed, but the comparison is case-sensitive, and a lower-case s on the line was rejected when tried.
An empty cbc:ID on the line fails here, not under BR-CO-04, which only asks for the element to exist. When tried, it also brought PEPPOL-EN16931-R008.
A listed code is accepted even when it is the wrong category for the item. Consistency with the breakdown is tested by the category rules, not by this one.
| Term | Meaning | UBL element |
|---|---|---|
| BT-151 | Invoiced item VAT category code | cac:InvoiceLine/cac:Item/cac:ClassifiedTaxCategory/cbc:ID (cac:CreditNoteLine/cac:Item/cac:ClassifiedTaxCategory/cbc:ID in a credit note) |
How an integration ends up here
Possible causes, from the shape of the rule rather than from measured usage:
- The item tax code from the product master, such as
SRorZR, is copied onto the line without translation. - The breakdown is built through a translation table but the lines are not, so the two carry different code sets.
- A description such as
Standardor a rate such as20is written in the code field. - A library or template produces the code in lower case.
How to fix it
- Use the finding location to find the line and its current code.
- Translate it to the permitted code for the category the item was taxed in, using the same mapping as the breakdown.
- Confirm that the line now falls into a breakdown with the same category and rate, so that breakdown taxable amount matches its lines.
- Reject unmapped item tax codes at export time.
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 line is coded SR while its breakdown is coded S
<cac:TaxSubtotal>
<cbc:TaxableAmount currencyID="GBP">25.00</cbc:TaxableAmount>
<cbc:TaxAmount currencyID="GBP">5.00</cbc:TaxAmount>
<cac:TaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>20</cbc:Percent>
<!-- tax scheme omitted from this fragment -->
</cac:TaxCategory>
</cac:TaxSubtotal>
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="C62">2</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="GBP">25.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Example service</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>SR</cbc:ID>
<cbc:Percent>20</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<!-- price omitted from this fragment -->
</cac:InvoiceLine>Fragment of the corrected invoice: the line uses the Standard rated code S
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="C62">2</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="GBP">25.00</cbc:LineExtensionAmount>
<cac:Item>
<cbc:Name>Example service</cbc:Name>
<cac:ClassifiedTaxCategory>
<cbc:ID>S</cbc:ID>
<cbc:Percent>20</cbc:Percent>
<cac:TaxScheme>
<cbc:ID>VAT</cbc:ID>
</cac:TaxScheme>
</cac:ClassifiedTaxCategory>
</cac:Item>
<!-- price omitted from this fragment -->
</cac:InvoiceLine>The failing invoice has SR in the line item's cac:ClassifiedTaxCategory/cbc:ID; the corrected one has S, and nothing else differs. Two breakdown rules also fire, because with SR on the only line nothing in the document is Standard rated while the breakdown still is. BR-S-01 objects to a Standard rated breakdown with no Standard rated line, allowance or charge behind it. BR-S-08 finds no Standard rated line at 20% to account for the 25.00 taxable amount. Correcting the code clears all three.
What the validator reported
- The failing invoice reports BR-CL-18, BR-S-01 and BR-S-08. The corrected document passes every layer with no findings.Download the failing XMLDownload the corrected XML
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
InvoiceandCreditNote. In a credit note the line iscac:CreditNoteLine; withSRon its line it reported the same three rules when tried. - The companions depend on the category the line should have had. When tried,
ZRon the Zero rated line of a mixed invoice broughtBR-Z-08instead. - If the breakdown carries the same wrong code, the category rules fall silent and
BR-CL-17is reported beside this rule instead. - Reported by the EN 16931 layer; the Peppol layer passes the recorded example.
Related rules
- BR-CL-17 applies the same code list to the VAT breakdown and document-level allowances and charges
- BR-CO-04 requires the line category code that this rule checks
- BR-S-01 fires with this rule when the miscoded line leaves a Standard rated breakdown unsupported
- BR-S-08 recalculates the Standard rated taxable amount without the miscoded line
- Browse every rule in the reference
- Background: Understanding EN 16931 validation errors
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-CL-18 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.
