Machine-readable RFC 9457 problem responses for every client-visible API failure, with stable type URIs, extension fields for correlation, and a catalog that prevents ad hoc error shapes from leaking internal state or bypassing retry semantics.
Package status: AI-assisted reference package. Static package validation has passed; implementation scenarios remain not run and human domain review is required before stable adoption.
Decision
Every HTTP API error that a client can observe returns a single problem-details object aligned with RFC 9457. Human-readable detail is secondary to a stable type URI constructed as {catalog_uri_base}/{uri_suffix} from entries in error-catalog.yaml. Internal exception classes, stack traces, and database identifiers never appear in client payloads. Retryable failures expose machine-readable extension fields so generic clients can honor rate limits and idempotency without parsing prose.
Scope
- Synchronous REST and RPC-style HTTP responses for 4xx and 5xx outcomes visible to external integrators.
- Problem type registry, extension field vocabulary, correlation identifiers, and validation error array schema.
- Mapping from domain failures to catalog entries without leaking authorization distinctions beyond what the product intentionally exposes.
Outside this block
- GraphQL error extensions with a separate schema (may reference the same catalog URIs but is not specified here).
- Non-HTTP transports such as WebSocket close codes or gRPC status details.
- Localization of end-user marketing copy unrelated to API integrators.
Contract
- Every client-visible error response includes
Content-Type: application/problem+jsonand a body with at leasttype,title, andstatusmatching the HTTP status code per RFC 9457. - The
typevalue equals{catalog_uri_base}/{uri_suffix}for a catalog entry; unknown types are rejected by the response filter in non-development environments. - Extension field
correlation_idis required on all client-visible errors (every 4xx and 5xx in this profile); it matches the value recorded in server logs and theX-Request-Idheader when present. - Per catalog entry,
required_extensionsandoptional_extensionsinerror-catalog.yamlare enforced; missing required extensions fail the response filter. - Validation failures use type
validationwith requirederrorsarray; each element includesfieldandsub_typepererrors_array_schema, not raw database constraint names. - Catalog types for HTTP 502 and 503 are
bad-gatewayandservice-unavailable; both requireretryable: trueandretry_after_seconds. - Clients and gateways must ignore unknown extension fields when
unknown_extension_behaviorisignore; they must not treat unknown extensions as errors. - Authorization failures return catalog types that do not reveal whether the resource exists when the product policy requires uniform 404/403 behavior.
- Internal-only diagnostics are stored server-side; they are never copied into the problem
detailfield for external callers.
Implementation guidance
- Centralize problem construction in one module per service boundary so controllers cannot emit ad hoc JSON error shapes.
- Register new types in the catalog before code references them; CI fails when code mentions a type absent from the registry.
- Bind correlation identifiers at the edge for every client-visible outcome and propagate them through downstream calls.
- Document type URI construction in operator runbooks as base plus suffix, not ad hoc string concatenation in each service.
Failure handling and safeguards
- If problem serialization fails, return catalog type
internalwith correlation_id rather than an empty body or HTML error page. - If an upstream dependency times out, emit 503 with type
service-unavailableand retry extensions when the operation is safe to retry. - Rate-limit responses must not include tenant-identifying detail in extension fields beyond what the authenticated caller already knows.
- During catalog migration, maintain alias suffix entries for deprecated type URIs until the profile deprecation window expires.
Verification and operations
- Contract tests assert Content-Type, correlation_id on 4xx and 5xx, catalog membership, and per-type required extensions.
- Monitor unknown-type filter rejections; spikes indicate undeployed catalog updates or rogue services.
- Sample production 5xx problems monthly to confirm no stack fragments appear in
detail.
Adoption assumptions
- Names and numeric values in
example.yamlanderror-catalog.yamlare an adoption profile, not universal defaults. - The adopting team owns the catalog URI namespace, correlation id format, and mapping from domain exceptions to problem types.