Problem Details
Problem details is the API error-body format defined by RFC 9457, which replaces RFC 7807. It gives clients structured information about a failure when an HTTP status code alone cannot explain what happened or how to respond.
In the RFCโs insufficient-credit example, the HTTP 403 response communicates the general status. The body identifies the particular problem and supplies the balance and account links. A client uses the HTTP status together with the problem type and its defined fields.
The members, read as instructions to client code
| Member | What it is | What a client should do with it |
|---|---|---|
type | A URI reference identifying the problem type; defaults to about:blank when absent | Use the resolved URI as the primary problem identifier. RFC 9457 advises against automatically fetching it except when providing information to developers |
status | The origin serverโs HTTP status, repeated as advisory information | Generic HTTP handling uses the response status. The body copy helps when HTTP metadata is lost or an intermediary changes the status |
title | A short advisory summary, normally stable for the problem type except for localization | Display or log it where appropriate; do not use its wording as the problem identifier |
detail | A human-readable explanation of this occurrence, focused on helping the client correct the problem | Show it where safe and useful. RFC 9457 recommends against parsing it for information; use structured extensions for client logic |
instance | A URI reference identifying this occurrence | Record it to correlate the problem during support and investigation |
The members serve different purposes. type identifies the problem; status carries HTTP status information; instance identifies an occurrence; extensions supply structured values such as a balance or field errors. title and detail explain the problem to people.
The rule to carry is this: identify the problem by type, then decide what to do using status and whatever structured members that type defines. Decisions based on the text of title or detail break when the wording or its localization changes.
An absent type defaults to about:blank, so 404 and 503 responses can share that identifier while requiring different handling. Status alone does not settle retry safety: a 503 after a non-idempotent action may leave the effect unknown, while a read contract may allow bounded retries after a 404 caused by visibility delay. Combine the operationโs retry contract with the error meaning and structured fields. Within a known type, an available balance or list of invalid fields can guide the next action. Parsing prose instead creates a fragile dependency on wording.
Extensions are how an error format evolves
Problem types can define extensions for structured details. The RFCโs examples include balance information and a list of field validation errors.
RFC 9457 requires clients to ignore extensions they do not recognize. This permits additions that leave the existing problem semantics intact. A client that rejects an unknown extension breaks whenever a provider adds one, which defeats the purpose of allowing extensions.
Introducing a new problem type is a different question, and it deserves a stated expectation. A client that treats an unknown type as a failure of the class the status code indicates keeps working; one that switches exhaustively on known types does not. Saying which behavior you expect is part of the contract, and it is the difference between a new error type being routine and being a breaking change.
What not to put in it
- Internal debugging detail. Keep stack traces and sensitive implementation data in logs. Give clients enough information to correct the problem and an occurrence identifier to use with support.
- A requirement to display the text verbatim. Human-readable
titleanddetailmay be suitable for display, but the caller chooses presentation and localization. Write safe, useful text without making its exact wording part of the machine contract. - Anything an unauthenticated caller should not learn. An error is a response to whoever asked, including someone probing, so distinguishing no such record from you may not see this record is a disclosure decision rather than a helpfulness one.
Three rules are worth taking even if you never adopt the format. Give each failure type one stable machine-readable identifier that never changes. Keep human text out of client logic by construction. Carry structured extras in members that clients ignore when they do not recognize them, so the error surface can grow without a new version. The complementary half โ telling a client whether and when to try again โ is covered under Retry-After and backoff, and how errors sit inside the wider interface obligation is worked through in You Cannot Un-publish an API.
References
Discover more from Insightful Data Lab
Subscribe to get the latest posts sent to your email.
