RFC 9457 Problem Details for HTTP APIs
Back to httpstatuses.net
RFC 9457 Problem Details for HTTP APIs
RFC 9457 defines a standard error response body for HTTP APIs. JSON responses use the IANA-registered application/problem+json media type.
I use Problem Details after choosing the correct HTTP status code. The body explains the API-specific problem; it does not replace the status code understood by clients, proxies, caches, and monitoring tools. If the status is still unclear, start with the REST API status code chooser.
The producer and client contract
All five standard members are optional. Producers can send only the members that help, and an omitted type resolves to about:blank. The actual HTTP status is authoritative for the exchange; a body status is advisory and, when present, must match the status sent by the origin server.
type is the resolved URI that clients use as the primary machine-readable identifier.
title is a stable human-readable summary of the type. detail explains one occurrence.
instance identifies one occurrence and can be a dereferenceable URI or an opaque URI.
Clients branch on the resolved type, not on title or detail.
Clients ignore unrecognized extensions and any standard member whose JSON type is wrong. They continue processing the rest of the object.
Clients should not automatically fetch type URIs during normal error handling. Developer tools can offer that as an explicit debugging action.
about:blank adds no semantics beyond the status code. A custom type is useful when clients need stable application-specific semantics, such as distinguishing an order-state conflict from other conflicts.
Problem Details keeps HTTP semantics and headers
The body does not replace status-specific headers. A 401 response still requires WWW-Authenticate. A 429 response can send Retry-After to tell the client how long to wait.
401 with an authentication challenge
HTTP/1.1 401 Unauthorized<br>Content-Type: application/problem+json<br>WWW-Authenticate: Bearer realm="orders"
"type": "https://api.example.com/problems/authentication-required",<br>"title": "Authentication required",<br>"status": 401<br>429 with retry timing
HTTP/1.1 429 Too Many Requests<br>Content-Type: application/problem+json<br>Retry-After: 60
"type": "https://api.example.com/problems/rate-limit",<br>"title": "Request rate limit exceeded",<br>"status": 429<br>500 without implementation secrets
HTTP/1.1 500 Internal Server Error<br>Content-Type: application/problem+json
"type": "https://api.example.com/problems/internal-error",<br>"title": "Internal server error",<br>"status": 500,<br>"instance": "urn:example:problem:01K0ABCDEF8Z7R6W5V4T3S2Q1P"<br>The 500 response returns only a non-sensitive occurrence reference. Keep the stack trace, query text, credentials, internal hostnames, and debugging context in protected server logs.
Validation errors as an extension
A 422 Unprocessable Content response can add an errors extension with one entry per invalid field. This follows the extension pattern shown in RFC 9457 without turning each field error into a separate top-level problem.
HTTP/1.1 422 Unprocessable Content<br>Content-Type: application/problem+json
"type": "https://api.example.com/problems/validation-error",<br>"title": "Request validation failed",<br>"status": 422,<br>"errors": [<br>{ "detail": "must be a valid email address", "pointer": "/email" },<br>{ "detail": "must be 18 or greater", "pointer": "/age" }<br>Copy validation example
An errors collection represents multiple occurrences of one problem type. When several problems have disparate types, return the most relevant or urgent problem. Avoid a generic envelope that mixes unrelated types because it does not map cleanly to HTTP semantics. Use 400 Bad Request when the request itself is malformed; use 422 when validly encoded content cannot be processed.
OpenAPI 3.1 schemas
The base schema keeps all standard members optional and allows problem-specific extensions. The validation subtype fixes its identity and defines the errors extension. Use schemas to check producers; RFC 9457 still requires tolerant clients to ignore wrong-typed standard members.
openapi: 3.1.0<br>info:<br>title: Example API<br>version: 1.0.0<br>paths: {}<br>components:<br>schemas:<br>Problem:<br>type: object<br>properties:<br>type:<br>type: string<br>format: uri-reference<br>default: about:blank<br>title:<br>type: string<br>status:<br>type: integer<br>minimum: 100<br>maximum: 599<br>detail:<br>type: string<br>instance:<br>type: string<br>format: uri-reference<br>additionalProperties: true<br>ValidationProblem:<br>allOf:<br>- $ref: '#/components/schemas/Problem'<br>- type: object<br>required: [type, errors]<br>properties:<br>type:<br>type: string<br>format: uri-reference<br>const: https://api.example.com/problems/validation-error<br>errors:<br>type: array<br>minItems: 1<br>items:<br>type: object<br>required: [detail, pointer]<br>properties:<br>detail:<br>type: string<br>pointer:<br>type: string<br>format: json-pointer<br>additionalProperties: false<br>Copy OpenAPI schema
Problem type document template
Publish a stable type URI with the type's title, recommended status, meaning,...