Engineering · · 4 min read

Invoice Validation Errors You Can Prevent (and How)

The invoice validation errors that cause silent Peppol rejections — and the layered checks that catch them before a document ever leaves your access point.

Validation errors, not delivery, are what break e-invoicing

When a Peppol invoice "doesn't go through", the instinct is to suspect the network. Almost always it's validation — the document is delivered, fails a rule at the receiver's access point, and is refused. The good news: nearly every one of these failures is preventable before the document ever leaves your side, if you validate in layers.

If the four-corner flow is new, start with how e-invoicing works and what a Peppol Access Point is. This article is about the checks that sit between "created" and "sent".

The layered validation pipeline

A serious access point runs every outbound document through a sequence of checks, each catching a different class of error:

  1. UBL 2.1 XSD — structural validity. Is it well-formed, are elements in the right place?
  2. Business rules — do the numbers reconcile? Line totals, document totals, tax subtotals.
  3. Code lists — are currency, country, unit, tax-category codes and participant schemes valid values?
  4. CEN EN 16931 + Peppol BIS Schematron — the mandatory European semantic baseline.
  5. Jurisdiction packs — PINT and national CIUS rules, selected by the document's CustomizationID.

The rule that governs the whole pipeline: an error means reject; only a warning may pass. If any layer raises an error, the document must not be transmitted.

The errors you'll actually hit

1. Tax totals that don't reconcile

The single most common failure. EN 16931 requires that line-level amounts, tax subtotals and document totals all agree to the cent. Rounding applied inconsistently — per line versus per document — is the usual culprit. Fix it by rounding once, in a defined place, and asserting the three levels match before you send.

2. Wrong or missing CustomizationID

The CustomizationID declares which specification applies, and the validator routes the document to the matching rule set based on it. Get it wrong and the invoice is checked against the wrong Schematron — see Peppol vs PINT for how the same UBL document can require completely different rules. For Oman specifically, the exact identifiers are catalogued in the PINT OM CustomizationID reference.

3. Invalid identifiers and schemes

Participant IDs, endpoint IDs and their scheme identifiers must be valid and correctly formatted. A buyer ID under the wrong scheme, or a scheme not recognised for the destination, produces a hard error — and often a confusing one, because the document looks correct to a human.

4. Stale or invalid code-list values

Currency, country, unit and tax-category codes are validated against controlled lists that change over time. A value that was valid last year, or a code list your system hasn't refreshed, will fail. Keeping code lists current is an operational task, not a one-off.

5. Missing mandatory fields

Each profile mandates its own set of required fields. A field that's optional in one jurisdiction is mandatory in another — which is exactly why a single canonical invoice needs profile-aware validation per destination, the model described in the multi-country e-invoicing API.

Why "validate at your boundary" matters

If the receiver's access point is the first thing to reject your invoice, you've already lost time and created an exception to chase. Validating at your boundary turns a compliance problem into a testing problem:

  • You control when and how errors surface.
  • You can run the official sample sets for each profile and treat any failure as a bug in your implementation, not a matter of interpretation.
  • You keep a dated evidence trail that every transmitted document passed.

This discipline is what separates a robust rollout from one that fails intermittently in production — a theme also covered in the Peppol onboarding checklist for finance teams.

A prevention checklist

  • [ ] Round tax amounts once, in a defined place; assert line/tax/document totals agree.
  • [ ] Set the CustomizationID from the actual destination profile, never hard-coded.
  • [ ] Validate participant IDs and schemes against the destination's requirements.
  • [ ] Refresh code lists on a schedule; fail closed on unknown values.
  • [ ] Run UBL XSD + EN 16931 + BIS + jurisdiction Schematrons on every document.
  • [ ] Block on error, log every failure with correlation IDs.
  • [ ] Re-run the official sample sets on every release.

How GoRoute helps

GoRoute (POP000991) is a certified Peppol Access Point and SMP that runs exactly this layered pipeline — UBL, business rules, code lists, CEN EN 16931 + Peppol BIS, and per-jurisdiction PINT/CIUS Schematrons compiled with Saxon-HE — before any document is transmitted, across 50+ countries from one REST API. Errors are caught at your boundary, not the receiver's. Book a demo or read how to choose a Peppol Access Point.


Sources: EN 16931; Peppol BIS Billing 3.0; OpenPeppol.

Frequently asked questions

Why do e-invoices get rejected on Peppol?
Most rejections come from validation failures, not transport problems. The document reaches the receiver's access point, fails a Schematron or business rule there, and is refused. The common causes are wrong or missing identifiers, tax totals that don't reconcile, an incorrect CustomizationID, and invalid code-list values.
What is the difference between a Schematron error and a warning?
An error means the document breaks a mandatory rule and must be rejected. A warning flags something questionable that is still allowed to pass. A well-built validator blocks on every error and lets only warnings through, so nothing non-compliant is ever transmitted.
What are the most common invoice validation errors?
Tax totals that don't add up (line totals vs document totals vs tax subtotals), an incorrect or missing CustomizationID, invalid participant or scheme identifiers, wrong currency or country codes from the code lists, and missing mandatory fields required by EN 16931 or the jurisdiction profile.
How do I validate an invoice before sending it?
Run it through a layered pipeline — UBL 2.1 XSD, business-rule checks on totals, code-list validation, then the CEN EN 16931 and Peppol BIS Schematrons, plus any jurisdiction pack (such as PINT). Do this at your own boundary so failures are caught before transmission, not by the receiver.
What does an incorrect CustomizationID cause?
The CustomizationID tells the validator which rule set to apply. If it's wrong, the document is checked against the wrong Schematron — so it either fails outright or, worse, passes the wrong rules and is rejected downstream. Matching the CustomizationID to the actual document profile is essential.
Can code-list values really cause a rejection?
Yes. Currency codes, country codes, unit codes, tax category codes and participant schemes are all validated against controlled code lists. A value that isn't in the current list — or a stale list on your side — produces a hard error even when the rest of the invoice is correct.
How do I stop the same validation errors recurring?
Treat validation as a testing problem. Keep your code lists and Schematron artefacts current, run the official sample sets on every release, block on errors in your pipeline, and log every failure with correlation IDs so patterns surface early rather than in production.

Related posts

Building on Peppol?

GoRoute is a certified Peppol Access Point & SMP. Book a demo or read the docs to get started.

Book a demo Read the docs