Skip to content

Ironfang Finance - Rule reference

PEPPOL-EN16931-CL002: Use one of the 19 Peppol UNTDID 5189 codes as the allowance reason code

On an allowance marked false, cbc:AllowanceChargeReasonCode must be one of the 19 UNTDID 5189 codes Peppol lists, such as 95. A padded 095 fails.

Peppol BIS BillingFatal: the document is invalidCode listsAllowances and charges

On this page

The short answer

PEPPOL-EN16931-CL002 fails when cbc:AllowanceChargeReasonCode in an allowance whose cbc:ChargeIndicator reads exactly false is not one of the 19 codes on the Peppol UNTDID 5189 list. In the recorded example the line discount was sent as 095; the code is 95, with no padding.

The Peppol list and the one BR-CL-19 checks on the EN 16931 layer are identical, so a wrong code is normally reported by both. They differ in which allowances they look at: this rule only sees an indicator written as the exact text false.

What the rule checks

The allowance is recognised by the text of cbc:ChargeIndicator, compared exactly with false. When tried, false with spaces around it, which the schema accepts, took the allowance out of this rule: a bad code there was reported by BR-CL-19 alone.

An indicator of 0 is a valid schema boolean too, but not the text false. When tried with the code 095, it reported BR-CL-19 and PEPPOL-EN16931-R043, which accepts only true or false, and not this rule.

The code is trimmed before the comparison, and what remains must equal a listed code exactly; a leading zero makes a different value, as 095 shows.

The finding location says which allowance holds the code: in the recorded example the first cac:AllowanceCharge of the first invoice line.

TermMeaningUBL element
BT-98Document level allowance reason codecac:AllowanceCharge/cbc:AllowanceChargeReasonCode
BT-140Invoice line allowance reason codecac:InvoiceLine/cac:AllowanceCharge/cbc:AllowanceChargeReasonCode (cac:CreditNoteLine in a credit note)

How an integration ends up here

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

  • Codes are formatted to a fixed width of three digits so that 100 to 105 line up with the rest, which turns 95 into 095.
  • Codes are stored as numbers and written out with a display format that pads them.
  • A charge code or an internal discount type is written on an allowance.
  • A lookup shared by allowances and charges hands a UNTDID 7161 code to a discount.

How to fix it

  1. Use the finding location to find the allowance and the discount it came from.
  2. Take the code from the Peppol list for UNTDID 5189 and write it as text without leading zeros: 95 Discount, 100 Special rebate, 41 Bonus for works ahead of schedule.
  3. Write cbc:ChargeIndicator as the plain text false on every allowance, so that both layers apply the same checks.
  4. If no code fits, send cbc:AllowanceChargeReason alone.

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 allowance reason code is padded to 095

<cac:InvoiceLine>
  <cbc:ID>1</cbc:ID>
  <!-- note, quantity, amounts and order line reference omitted from this fragment -->
  <cac:AllowanceCharge>
    <cbc:ChargeIndicator>false</cbc:ChargeIndicator>
    <cbc:AllowanceChargeReasonCode>095</cbc:AllowanceChargeReasonCode>
    <cbc:AllowanceChargeReason>Example discount</cbc:AllowanceChargeReason>
    <cbc:MultiplierFactorNumeric>5</cbc:MultiplierFactorNumeric>
    <cbc:Amount currencyID="GBP">2.00</cbc:Amount>
    <cbc:BaseAmount currencyID="GBP">40.00</cbc:BaseAmount>
  </cac:AllowanceCharge>
  <!-- line charge, item and price omitted from this fragment -->
</cac:InvoiceLine>

Fragment of the corrected invoice: the reason code is 95, Discount

<cac:InvoiceLine>
  <cbc:ID>1</cbc:ID>
  <!-- note, quantity, amounts and order line reference omitted from this fragment -->
  <cac:AllowanceCharge>
    <cbc:ChargeIndicator>false</cbc:ChargeIndicator>
    <cbc:AllowanceChargeReasonCode>95</cbc:AllowanceChargeReasonCode>
    <cbc:AllowanceChargeReason>Example discount</cbc:AllowanceChargeReason>
    <cbc:MultiplierFactorNumeric>5</cbc:MultiplierFactorNumeric>
    <cbc:Amount currencyID="GBP">2.00</cbc:Amount>
    <cbc:BaseAmount currencyID="GBP">40.00</cbc:BaseAmount>
  </cac:AllowanceCharge>
  <!-- line charge, item and price omitted from this fragment -->
</cac:InvoiceLine>

Only the reason code of the line allowance differs: 095 in the failing invoice, 95 in the corrected one. The failing document also reports BR-CL-19, the EN 16931 check of the same code against the same list, at the same element.

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 Invoice and CreditNote; when tried, 095 on a credit note line allowance reported this rule and BR-CL-19.
  • A Peppol BIS Billing 3.0 rule. With the indicator written as false it never fires without BR-CL-19, since the lists match, while BR-CL-19 can fire alone when the indicator is spelt another way.
  • Charges are checked against UNTDID 7161 by PEPPOL-EN16931-CL003, the matching rule for an indicator of true.

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-28.1: source checked 2026-09-28, explanation last updated 2026-09-28.

The official definition of PEPPOL-EN16931-CL002 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.