This is the field that produces the phone call. An invoice for a substantial sum, legally correct in every respect, refused by a receiver whose message says something like "reason code not permitted for this category". The finance team is certain the treatment is right. It usually is. The treatment is not what failed.
A structured invoice cannot express "no VAT" as an absence. It has to express it as a category, a rate, and — where the rate is nil — a stated reason. Those three things have to be mutually consistent, drawn from maintained lists, and permitted by whichever national or sectoral profile the receiver validates against. Three constraints, three maintainers, one field.
Why the reason exists
A number of zero is ambiguous in a way that matters. Consider four supplies that all show no tax on the invoice.
An intra-Community supply of goods to a registered customer in another Member State is zero-rated: the supply is taxable, the rate applied is nil, and the customer accounts for acquisition tax. A supply of certain financial services is exempt: it is not taxable at all, and the difference affects the supplier's own right to deduct input tax. A supply to a customer outside the scope of the tax altogether is something else again. And a supply subject to the reverse charge is taxable, at a real rate, with the liability moved to the buyer.
Four legal positions. One number. The reason field is what separates them, and it separates them for three audiences at once: the buyer's accounts payable system deciding whether it owes self-assessed tax, the auditor reconstructing the position years later, and in a reporting regime, the administration receiving the data in near real time.
The shape of the problem
| Treatment | Rate on the line | What the document must state | The failure that recurs |
|---|---|---|---|
| Standard or reduced rate | The applicable percentage | Category and rate; no reason required | A rate that is correct for the wrong Member State |
| Zero-rated supply | Nil | Category, nil rate, and the reason establishing the zero rating | The customer's registration is present but was never verified |
| Exempt supply | Nil | Category, nil rate, and a reason identifying the exemption | The reason names a general exemption where the profile requires a specific one |
| Reverse charge | Nil on the document | Category indicating shifted liability, plus the statement required of the supplier | The document carries a shifted-liability category and a domestic rate, contradicting itself |
| Outside scope | Nil or absent | Category showing the supply is not within the tax | Treated as exempt, which is a different legal position with different consequences |
| Margin schemes and special regimes | Varies | Category plus the reference the regime requires | Handled as an ordinary rate because the source system has no concept of the regime |
Read down the last column. Almost none of those are technical faults. They are business facts that were never captured, or were captured once and never re-verified.
Where the values come from
The category itself is a code list entry, not a word your organisation invented. So is the reason, where a coded reason is used. Both are maintained externally, both change, and both are narrowed by whichever profile applies to the receiver. That layering is the whole difficulty and it is worth stating precisely.
The European semantic model defines the terms and says what kind of value each takes. The code lists supply the permitted values. A core invoice usage specification then restricts the set further for its own domain — making a reason mandatory where the standard made it optional, or permitting only a subset of the reasons the list contains. The receiver may narrow it again in rules they never published.
So the question "which code should I use?" has no site-wide answer, and any source that gives you one without asking which profile applies is selling something. What can be stated generally is the procedure: read the profile that governs the transaction, take the permitted set from it, map your internal categories onto that set deliberately, and record the mapping somewhere a successor can find.
The durable deliverable is not a list of codes. It is a documented mapping from the treatments your business actually applies to the values a given profile permits, with the reasoning attached. Codes change and profiles are revised. A mapping with reasoning survives both; a spreadsheet of values copied from a forum post does not.
Why it is nearly always inherited rather than chosen
Here is the mechanism that makes this a systematic problem rather than an occasional one.
During an implementation, somebody configures tax codes. There are more of them than anyone expected, the project is late, and the exemption reasons are the last thing configured. A plausible value is selected for each, the test invoices pass, and the configuration is never revisited. Every document afterwards inherits that choice.
Then the business changes. It starts supplying a new service, or selling into a new Member State, or applying a regime it did not use before — and the new activity is mapped onto the nearest existing tax code, because that is what the system offers. The reason attached to that code was chosen for the old activity. It is now attached to a different one, and nothing anywhere reports the fact.
This is why exemption reasons fail disproportionately at the point a business grows rather than at go-live. Go-live was tested. Growth was not.
Testing it before a customer does
The corpus that matters is not the clean one. Build a test set containing the awkward cases specifically: an intra-Community supply, an exempt supply, a reverse-charged supply, a document mixing a standard-rated line with an exempt line, and a credit note correcting each. Then run it through the validation stack the receiver actually operates rather than through a public validator alone, because the gate that rejects in production is the one nobody published.
A mixed-treatment document deserves particular attention. Multiple categories in one invoice mean multiple breakdown entries, each with its own rate and, where applicable, its own reason. It is the case most likely to be constructed correctly on a single-line test and incorrectly in production.
What to do when one is rejected
Work outward from the document rather than inward from the law, because the law is probably not what failed.
Check first that the category, the rate and the reason are internally consistent — a shifted liability with a positive rate is the commonest contradiction. Check next that the reason is in the set the applicable profile permits, which is not the same as being in the code list. Check third that the underlying facts still support the treatment: a customer registration that was valid at onboarding and has since been deregistered will produce exactly this failure, and the fix is not in the invoice at all.
Only after those three should anyone reopen the question of whether the treatment itself is right. In practice it usually is. What was wrong was the sentence, not the thought behind it.