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.
A complete HTTP response
HTTP/1.1 409 Conflict
Content-Type: application/problem+json
{
"type": "https://api.example.com/problems/order-conflict",
"title": "Order state conflict",
"status": 409,
"detail": "Order 123 has already been shipped.",
"instance": "https://api.example.com/problems/occurrences/7f3a"
}
The response line carries the real 409 Conflict status. The JSON status member repeats 409 for convenience, but RFC 9457 calls that member advisory. A server that includes it must use the same code in the actual HTTP response.
The five standard members
| Member | Use |
|---|---|
type | A URI reference that identifies the problem type. Clients use the resolved URI as the primary machine-readable identifier. |
title | A short human-readable summary of the type. Keep it stable across occurrences except for localization. |
status | The advisory HTTP status code generated for this occurrence. It does not override the response status. |
detail | A human-readable explanation for this occurrence. Help the client correct the request; do not make clients parse it. |
instance | A URI reference that identifies this specific occurrence. It can be dereferenceable or an opaque identifier. |
These members are defined in RFC 9457 section 3.1. Extension members carry machine-readable data that is specific to a problem type. Clients must ignore extensions they do not recognize.
Use about:blank for status-only semantics
If type is absent, its value defaults to about:blank. That type adds no meaning beyond the HTTP status code. With about:blank, the title should use the recommended status phrase, such as Not Found for 404 Not Found.
Use about:blank when the status code already says enough. Define a custom problem type only when clients need stable application-specific semantics.
Define custom problem types carefully
- Prefer an absolute, stable type URI under a domain you control.
- Make an HTTP or HTTPS type URI resolve to human-readable documentation when possible.
- Document the type URI, short title, recommended HTTP status, and every extension member.
- Keep occurrence-specific values in
detail,instance, or extensions instead of changingtitle. - Check the IANA HTTP Problem Types registry before creating a type intended for broad reuse.
RFC 9457 recommends absolute type URIs and says resolvable type URIs should provide HTML documentation. A type URI is an identifier; clients should not fetch it automatically during normal error handling.
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
Content-Type: application/problem+json
{
"type": "https://api.example.com/problems/validation-error",
"title": "Request validation failed",
"status": 422,
"errors": [
{ "detail": "must be a valid email address", "pointer": "#/email" },
{ "detail": "must be 18 or greater", "pointer": "#/age" }
]
}
Use 400 Bad Request when the request itself is malformed. Use 422 when the content syntax is valid but the instructions cannot be processed. The 400 vs 411 vs 413 vs 422 comparison covers the surrounding choices.
Security and privacy
- Do not expose stack traces, SQL, internal hostnames, secrets, or authorization rules that help an attacker.
- Do not put personal data or sensitive identifiers in
detail, extensions, or a publicinstanceURI. - Protect dereferenceable instance resources with the same authorization checks as the underlying data.
- Log private debugging details server-side and return a safe occurrence identifier to the client.
RFC 9457's security considerations specifically warn about implementation leaks, privacy risks, and disagreement between the actual response status and the advisory member.
Primary references
- RFC 9457: Problem Details for HTTP APIs — the current standard, replacing RFC 7807.
- RFC 9110 HTTP Semantics: Status Codes — current HTTP status semantics.
- IANA HTTP Status Code Registry — registered status codes and references.
- IANA application/problem+json registration — the registered JSON media type.
For server failures, choose among 500, 502, 503, and 504 before writing the body. The 5xx comparison explains those boundaries.