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.

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

MemberUse
typeA URI reference that identifies the problem type. Clients use the resolved URI as the primary machine-readable identifier.
titleA short human-readable summary of the type. Keep it stable across occurrences except for localization.
statusThe advisory HTTP status code generated for this occurrence. It does not override the response status.
detailA human-readable explanation for this occurrence. Help the client correct the request; do not make clients parse it.
instanceA 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

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

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

For server failures, choose among 500, 502, 503, and 504 before writing the body. The 5xx comparison explains those boundaries.


HTTP status code lookup
REST API status code chooser
cURL command generator
By Ping Now, a website/API/service uptime monitor
Data from Wikipedia