Skip to content

Ironfang Finance - Rule reference

PEPPOL-EN16931-P0108: Put the second-hand means of transport code VATEX-EU-D in an exempt breakdown

VATEX-EU-D marks a second-hand means of transport, such as a used car, and is accepted only with category E. The recorded used car was coded K.

Peppol BIS BillingFatal: the document is invalidVATCode lists

On this page

The short answer

PEPPOL-EN16931-P0108 fails for each cac:TaxCategory that carries VATEX-EU-D while its cbc:ID is not E. The code signals that VAT on a second-hand means of transport, such as a used car, has been dealt with under the transitional arrangements for such vehicles, and the VATEX list allows it only with the exempt category.

The recorded example sells a used car to a buyer in Berlin and codes the breakdown and the line K, intra-community supply. The name of the code on the VATEX list begins with "Intra-Community acquisition", which makes K look right, but Peppol pairs VATEX-EU-D with E and nothing else.

What the rule checks

The rule upper-cases the exemption code before matching and then requires the category E, trimmed. When tried, vatex-eu-d in the K breakdown was reported just as the upper-case code was.

The recorded failure is this rule alone, because the rest of the document meets category K: both VAT identifiers, a delivery date and a deliver-to country are there, and a reason is given. With VATEX-EU-IC in place of VATEX-EU-D, the same document passed every layer when tried.

A zero rating does not work either. When tried, the used car breakdown and line coded Z with VATEX-EU-D reported this rule and BR-Z-10.

TermMeaningUBL element
BT-121VAT exemption reason codecac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:TaxExemptionReasonCode
BT-118VAT category codecac:TaxTotal/cac:TaxSubtotal/cac:TaxCategory/cbc:ID
BT-151Invoiced item VAT category codecac:InvoiceLine/cac:Item/cac:ClassifiedTaxCategory/cbc:ID

How an integration ends up here

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

  • The code is picked by its name on the VATEX list, "Intra-Community acquisition from second hand means of transport", and matched with the intra-community category.
  • A dealer system sets the category from the buyer country and the code from the vehicle record, so a used vehicle sold to another member state gets K with VATEX-EU-D.
  • Vehicle sales without VAT on the invoice are mapped to zero rated.

How to fix it

  1. Confirm how the sale is taxed. If the vehicle is sold under the arrangements for second-hand means of transport, the category is E and VATEX-EU-D stays.
  2. Set cbc:ID to E on the breakdown and on the lines it covers, with the rate 0. The corrected example needed nothing else: E requires a seller tax identifier, and its seller VAT identifier was present; the code counts as the reason BR-E-10 asks for.
  3. If the sale really is an intra-community supply, keep K and replace the code with VATEX-EU-IC, as PEPPOL-EN16931-P0106 expects.

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: a used car coded as an intra-community supply, K

<cac:TaxSubtotal>
  <cbc:TaxableAmount currencyID="GBP">25.00</cbc:TaxableAmount>
  <cbc:TaxAmount currencyID="GBP">0.00</cbc:TaxAmount>
  <cac:TaxCategory>
    <cbc:ID>K</cbc:ID>
    <cbc:Percent>0</cbc:Percent>
    <cbc:TaxExemptionReasonCode>VATEX-EU-D</cbc:TaxExemptionReasonCode>
    <cbc:TaxExemptionReason>Second-hand means of transport</cbc:TaxExemptionReason>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:TaxCategory>
</cac:TaxSubtotal>
<!-- totals and the start of the invoice line omitted from this fragment -->
<cac:Item>
  <cbc:Name>Used car</cbc:Name>
  <cac:ClassifiedTaxCategory>
    <cbc:ID>K</cbc:ID>
    <cbc:Percent>0</cbc:Percent>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:ClassifiedTaxCategory>
</cac:Item>

Fragment of the corrected invoice: the used car is exempt, E, with the same code

<cac:TaxSubtotal>
  <cbc:TaxableAmount currencyID="GBP">25.00</cbc:TaxableAmount>
  <cbc:TaxAmount currencyID="GBP">0.00</cbc:TaxAmount>
  <cac:TaxCategory>
    <cbc:ID>E</cbc:ID>
    <cbc:Percent>0</cbc:Percent>
    <cbc:TaxExemptionReasonCode>VATEX-EU-D</cbc:TaxExemptionReasonCode>
    <cbc:TaxExemptionReason>Second-hand means of transport</cbc:TaxExemptionReason>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:TaxCategory>
</cac:TaxSubtotal>
<!-- totals and the start of the invoice line omitted from this fragment -->
<cac:Item>
  <cbc:Name>Used car</cbc:Name>
  <cac:ClassifiedTaxCategory>
    <cbc:ID>E</cbc:ID>
    <cbc:Percent>0</cbc:Percent>
    <cac:TaxScheme>
      <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
  </cac:ClassifiedTaxCategory>
</cac:Item>

The failing invoice has K where the corrected one has E, in the breakdown and on the line for the used car; VATEX-EU-D, the reason text, both VAT identifiers and the delivery details are identical in the two. Only this Peppol rule is reported, since a K breakdown with a reason and the intra-community data passes the EN 16931 layer.

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. When tried, a credit note with VATEX-EU-D in an export breakdown, category G, reported this rule.
  • Only the Peppol layer checks the pairing; EN 16931 accepts VATEX-EU-D in any category through BR-CL-22.
  • An exempt breakdown with this code needs no buyer VAT identifier or delivery details, but they may stay: the corrected example keeps them and passed every layer.

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-P0108 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.