An error message has a job: tell the receiver enough about the failed state to choose the next correct action.
That sounds simple until a failure crosses a system boundary.
Inside System A, the fault may be highly specific: database lock conflict, stock reservation expired, downstream identity mismatch, missing authority token or sensor disagreement. System B may not understand those internals and should not need to.
Interface error translation converts the source failure into a form the receiver can understand and act on, while preserving the distinction that matters for repair.
It is a specialised branch below How Interfaces Work and How Interface Contracts Work. A successful contract explains not only how success crosses the boundary, but how failure does.
Internal Failure and Receiver Meaning Are Different Layers
The source system may know why it failed in great detail. The receiver needs a different question answered: what does this failure mean for me?
For example, an internal storage exception may translate to “temporary service unavailable — retry later.” An invalid identity record may translate to “input must be corrected before resubmission.” A policy rule may translate to “request not permitted under current conditions.”
The translator removes irrelevant implementation detail while preserving the operational class of the failure.
The Worst Translation Is “Something Went Wrong”
Generic errors simplify the sender’s interface and transfer complexity to the receiver.
If every failure becomes “error,” the receiver cannot know whether to retry, repair input, seek authority, wait, reconcile state or contact a human.
The interface has technically reported failure while destroying the information needed for recovery.
Useful Error Classes
Different domains need different taxonomies, but several classes recur:
- invalid input: the request itself must change;
- unauthorised or forbidden: identity or authority is insufficient;
- not found: the referenced object is unavailable or no longer exists;
- conflict: current state differs from the state the request assumed;
- rate or capacity limited: demand exceeds what can be accepted now;
- temporary unavailable: the service may recover without changing the request;
- unknown outcome: the sender cannot safely say whether the effect happened.
These classes matter because each implies a different repair path.
Preserve Retry Meaning
One of the most valuable facts an error can convey is whether retry is useful.
A malformed request should usually not be retried unchanged. A temporary overload may justify delayed retry. An unknown outcome should prompt status lookup before repeating a non-idempotent action.
This connects directly to How Retry Safety Works and How Handoff Timeouts Work.
Do Not Leak Internals That Do Not Belong Outside
Error detail can also reveal too much.
Internal file paths, database structure, security decisions, personal data or privileged operational details may not belong across the interface.
The translation layer therefore balances two needs:
- give the receiver enough meaning to recover;
- keep internal detail that is irrelevant, sensitive or unsafe inside the boundary.
Useful abstraction is not secrecy for its own sake. It is preserving the correct contract boundary.
Correlation Identity Lets Both Sides Talk About the Same Failure
A receiver-friendly error may omit internal detail, but operators still need to diagnose the exact event.
A correlation or case identifier links the external message to the richer internal record.
The user can say, “error reference A7K9,” and the operator can find the detailed trace without exposing it publicly.
This preserves both usability and provenance.
Do Not Translate Distinct Failures Into One False Meaning
Suppose a system maps “inventory unavailable,” “address invalid” and “carrier offline” into the same external error: “order failed.”
The receiver cannot distinguish repairable input from temporary infrastructure failure.
This is semantic compression. It may simplify the interface but destroys actionable distinction.
Error translation should compress implementation detail, not collapse different receiver actions into one label.
Worked Example: Payment Failure
A payment fails internally because the account has insufficient available funds.
The receiver does not need the bank’s internal ledger mechanics. It does need to know that retrying the same instruction immediately is unlikely to help unless the account state changes.
Contrast that with a temporary service outage, where the same request may succeed later. The two failures require different action even if both originate inside “the bank.”
Worked Example: Logistics
A carrier rejects a shipment booking.
“Rejected” is not enough. Was the address invalid? Weight outside service limits? Capacity unavailable? Pickup cut-off missed? Dangerous-goods information incomplete?
Each failure routes differently: repair data, change carrier, reschedule, repackage or seek specialist handling.
Error classification is therefore routing infrastructure.
Worked Example: Education
A wrong answer is an error signal, but “wrong” contains too little diagnostic meaning.
The teacher may translate the failure into categories such as prerequisite gap, representation error, procedure slip, misconception, reading error or incomplete checking.
The purpose is the same as an interface error taxonomy: preserve enough structure in the failure to select the next useful action.
Worked Example: Public Service
An application cannot proceed. A poor interface says “submission unsuccessful.”
A better interface distinguishes missing document, ineligible state, temporary outage, identity mismatch and review already in progress.
Clear error meaning reduces unnecessary calls, repeat submissions and citizen uncertainty.
Error Translation Can Change Across Versions
New systems often learn more precise failure states than old receivers understand.
The translation layer may map several new errors into an older broad category while preserving a machine-readable extension for newer clients.
This is version compatibility applied to failure semantics. The old receiver keeps working; the new receiver gains richer repair information.
Test the Error Contract
- List important internal failure states.
- Group them by what the receiver should do next.
- Preserve distinctions that change repair action.
- Remove internal detail that does not belong outside.
- Attach correlation identity for diagnosis.
- Mark retryable, repairable, permanent and unknown-outcome states.
- Test how old and new receivers interpret each error.
- Verify that human wording and machine code tell the same story.
The CivDJ Rotation
- Forward: internal fault → classification → boundary translation → receiver action.
- Backward: start from the desired repair action and ask what failure meaning must reach the receiver.
- Rotate: compare developer, operator, customer, auditor and security views of the same error.
A good error contract works across these views without leaking one audience’s unnecessary detail into another.
Failure crosses an interface well when the receiver loses implementation detail but keeps the meaning needed to recover.
Continue through How Interface Contracts Work, How Repair Routing Works and the master How X Works hub. The final article in this corridor asks what happens when temporary interface compromises accumulate for years.
