The short answer
PEPPOL-EN16931-R130 fails when cac:Price/cbc:BaseQuantity has a unitCode other than the one on the line quantity. In the recorded example the quantity is in C62 and the base quantity in H87. Give the base quantity the unit of the quantity, and if the price was quoted in another unit, restate the price and base quantity in the quantity unit.
Each code can be valid on its own; what fails is the disagreement. C62 (one) and H87 (piece) are both on the unit list, which is why the EN 16931 layer passes.
What the rule checks
The rule runs on each cbc:BaseQuantity that has a unitCode attribute and compares that code with the unitCode of the quantity on the same line: cbc:InvoicedQuantity in an invoice, cbc:CreditedQuantity in a credit note.
The comparison is a plain match of the two strings, with no unit conversion and no case folding. When tried, c62 against C62 failed here and under BR-CL-23, and unitCode=" C62 ", with spaces around the code, failed here alone.
Three situations are skipped. A base quantity with no unitCode is not checked; removing the attribute from the recorded base quantity gave a clean result when tried. A line with no quantity element is left alone, and BR-22 reports it. A line with no cbc:BaseQuantity has nothing to compare.
A quantity that exists without a unitCode still counts as a quantity, so a base quantity that has a unit fails against it. That is why a missing line unit reports this rule next to BR-23.
| Term | Meaning | UBL element |
|---|---|---|
| BT-150 | Item price base quantity unit of measure code | cac:InvoiceLine/cac:Price/cbc:BaseQuantity/@unitCode |
| BT-130 | Invoiced quantity unit of measure code | cac:InvoiceLine/cbc:InvoicedQuantity/@unitCode (cac:CreditNoteLine/cbc:CreditedQuantity/@unitCode in a credit note) |
| BT-149 | Item price base quantity | cac:InvoiceLine/cac:Price/cbc:BaseQuantity |
How an integration ends up here
Possible causes, from the shape of the rule rather than from measured usage:
- The price comes from a price list kept per kilogram, per metre or per pack, while the quantity is recorded in grams, centimetres or single items.
- Two mapping tables translate units, one for order or delivery lines and one for the price list, and they give the same local unit different codes, such as
C62in one andH87in the other. - The base quantity unit is fixed in the template while the line unit comes from the product.
- The line unit was corrected after a
BR-CL-23finding and the base quantity kept the old code.
How to fix it
- Compare the two
unitCodevalues on the failing line and decide which unit the quantity is really counted in. The quantity unit describes what was delivered, so keep it unless it is itself the wrong one. - If both codes mean the same thing to you, such as
C62andH87for single items, pick one and write it on both elements. Make the unit mapping produce a single code for each local unit. - If the price is quoted in a different unit, express the base quantity in the line unit. A price of 50 per kilogram against a quantity of 500 grams becomes a price of 50 for a base quantity of 1000
GRM. When tried, that line with a net amount of 25.00 passed every layer. - Do not only relabel the unit.
PEPPOL-EN16931-R120ignores units and divides the price by the base quantity as a plain number: when tried, the same line with the price per 1KGMfailed that rule too, because 500 x 50 is not 25.00, and writingGRMover a base quantity of 1 would leave that gap in place. - Leaving
unitCodeoffcbc:BaseQuantityalso passes, because the rule then has nothing to compare, but writing the same code as the quantity keeps the price self-describing.
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 quantity is in C62, the price base quantity in H87
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="C62">2</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="GBP">25.00</cbc:LineExtensionAmount>
<!-- item omitted from this fragment -->
<cac:Price>
<cbc:PriceAmount currencyID="GBP">12.5</cbc:PriceAmount>
<cbc:BaseQuantity unitCode="H87">1</cbc:BaseQuantity>
</cac:Price>
</cac:InvoiceLine>Fragment of the corrected invoice: both quantities are in C62
<cac:InvoiceLine>
<cbc:ID>1</cbc:ID>
<cbc:InvoicedQuantity unitCode="C62">2</cbc:InvoicedQuantity>
<cbc:LineExtensionAmount currencyID="GBP">25.00</cbc:LineExtensionAmount>
<!-- item omitted from this fragment -->
<cac:Price>
<cbc:PriceAmount currencyID="GBP">12.5</cbc:PriceAmount>
<cbc:BaseQuantity unitCode="C62">1</cbc:BaseQuantity>
</cac:Price>
</cac:InvoiceLine>Only the unitCode of cbc:BaseQuantity differs: H87 in the failing invoice, C62 in the corrected one, matching cbc:InvoicedQuantity. The failing document reports only PEPPOL-EN16931-R130. H87 is a recognised unit, so BR-CL-23 stays quiet, and the line calculation does not look at units, so PEPPOL-EN16931-R120 still finds 2 x 12.5 = 25.00.
What the validator reported
- The failing invoice reports PEPPOL-EN16931-R130. 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 comparison is withcbc:CreditedQuantity; when tried, a credited quantity inC62against a base quantity inH87reported this rule alone, as on the invoice. - This is a Peppol BIS rule, reported on the Peppol layer. The EN 16931 layer does not report the mismatch: it passes in the recorded example.
- An unrecognised code on either element is a separate finding,
BR-CL-23, and the two rules can be reported together for the same base quantity.
Related rules
- BR-23 requires the unit code on the line quantity that this rule compares against
- BR-CL-23 checks that each unit code is a recognised UN/ECE code
- PEPPOL-EN16931-R121 requires the price base quantity itself to be above zero
- PEPPOL-EN16931-R120 divides the price by the base quantity when it checks the line net amount
- Browse every rule in the reference
- Background: How Peppol invoice validation actually works
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 PEPPOL-EN16931-R130 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.
