---
name: rfc9457-problem-details
description: Design and review HTTP API error responses using RFC 9457 Problem Details (application/problem+json, application/problem+xml). Use when implementing API error handling, defining new problem types, validating error response payloads, or migrating from RFC 7807.
---

# RFC 9457 — Problem Details for HTTP APIs

RFC 9457 (July 2023, obsoletes RFC 7807) defines a standard, machine-readable format
for carrying error details in HTTP response content, so APIs do not need to invent
their own error formats or redefine the semantics of existing HTTP status codes.

Use this skill when:
- Implementing or reviewing error responses in an HTTP API.
- Defining a new problem type for an API.
- Validating that an error payload conforms to `application/problem+json`.
- Migrating an API from RFC 7807 to RFC 9457.

## Core rules

1. **Media type**: Serve JSON problem details with `Content-Type: application/problem+json`
   (XML variant: `application/problem+xml`). A server MAY respond with this type even if
   the client did not list it in `Accept`.
2. **Status code**: Problem details work with any status code but naturally fit 4xx and 5xx.
   If the `status` member is present, the generator MUST use the same status code in the
   actual HTTP response.
3. **Don't overuse**: If a plain status code is self-explanatory (e.g., 403 on a PUT for
   "write access disallowed"), don't define a problem type. If the application already has
   a suitable domain-specific error format, prefer that — problem details avoid the need
   for *new* fault formats, they don't replace existing ones.
4. **Type checking on consume**: If a member's value type does not match the specified
   type, consumers MUST ignore that member (process as if absent).
5. **Unknown extensions**: Clients MUST ignore extension members they don't recognize.

## Members of a problem details object

All members are optional. See `references/members.md` for full normative detail.

| Member | JSON type | Meaning | Key requirements |
|---|---|---|---|
| `type` | string (URI reference) | Identifies the problem type | Defaults to `"about:blank"` when absent. Consumers MUST use it as the primary identifier. Absolute URIs RECOMMENDED. Dereferencing SHOULD yield human-readable docs, but consumers SHOULD NOT auto-dereference (except for developer tooling). |
| `status` | number | HTTP status code generated by the origin server | Advisory only; MUST match the actual response status. |
| `title` | string | Short, human-readable summary of the problem *type* | SHOULD NOT change per occurrence, except localization. |
| `detail` | string | Human-readable explanation of this *occurrence* | Focus on helping the client correct the problem, not debugging info. Consumers SHOULD NOT parse it — use extensions instead. |
| `instance` | string (URI reference) | Identifies this specific occurrence | May be dereferenceable or an opaque identifier. Absolute URIs RECOMMENDED. |

### Canonical example

```http
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
Content-Language: en

{
 "type": "https://example.com/probs/out-of-credit",
 "title": "You do not have enough credit.",
 "detail": "Your current balance is 30, but that costs 50.",
 "instance": "/account/12345/msgs/abc",
 "balance": 30,
 "accounts": ["/account/12345", "/account/67890"]
}
```

`balance` and `accounts` are extension members defined by the problem type.

### Multiple problems

To convey several occurrences of the *same* problem type, define an extension
(e.g., an `errors` array with `detail` + JSON Pointer `pointer` entries — see
`references/examples.md`). For multiple problems of *different* types, it is
RECOMMENDED to report only the most relevant or urgent one; generic "batch"
problem types map poorly onto HTTP semantics.

## Defining a new problem type

A new problem type definition MUST document:
1. A type URI (typically `http`/`https` scheme, under your control, stable over time).
2. A title that appropriately describes it (short).
3. The HTTP status code it is used with.

Additionally:
- It MAY specify use of the `Retry-After` header where appropriate.
- The type URI SHOULD resolve to HTML documentation explaining how to resolve the problem.
  Non-resolvable URIs (e.g., `tag:` scheme) are allowed but resolvable ones are encouraged
  (switching later is a breaking change).
- Extension member names SHOULD start with a letter, SHOULD use only ALPHA, DIGIT, and `_`
  (for serialization in non-JSON formats), and SHOULD be at least three characters long.
- Before minting a new URI, check the IANA "HTTP Problem Types" registry
  (`https://iana.org/assignments/http-problem-types`) and reuse an existing type if one fits.
  Registered types MAY use that URI prefix; registration policy is Specification Required
  (vendor-/application-/deployment-specific values cannot be registered).

### about:blank

`about:blank` (the default `type`) means the problem has no semantics beyond the HTTP
status code. Its `title` SHOULD be the recommended HTTP status phrase (e.g., "Not Found"
for 404), though it MAY be localized.

## Security considerations

- Vet all information included in problem types and generated problems; risk is leaking
  information that compromises the system, access to it, or user privacy.
- Do not expose implementation internals (e.g., stack dumps) through error responses.
- `status` duplicates the HTTP status code; intermediaries may change the response code,
  and generic HTTP software will use the actual status code, not the member.

## References (bundled)

- `references/members.md` — full member-by-member normative requirements.
- `references/json-schema.json` — non-normative JSON Schema from Appendix A (spec text prevails).
- `references/examples.md` — validation-error example, XML format (RELAX NG schema, namespace
  `urn:ietf:rfc:7807`), embedding in HTML, and the RFC 7807 → 9457 change list.
