Skip to content
ADP
API Design PrincipleBETA

[ADP-401] HTTP Problem Basics

Overview

Error responses are an important component of any API. Clearly, HTTP status codes for errors (4xx, 5xx) do not provide sufficient information for API callers to accurately understand what has happened.

In the past, we might have introduced custom error codes to describe errors beyond standard HTTP status codes, but this is neither clear nor intuitive.

Currently, RFC 9457 provides a standard way to describe errors, and this ADP is based on RFC 9457 to provide a standard method for designing error responses.

Guidance

  • Error responses MUST comply with the HTTP Problem specification.
  • Error responses MUST use JSON format.
  • The Content-Type header of error responses MUST be application/problem+json.
  • Problem type design: see ADP-403.

Q & A

  • Can I add new fields to all HTTP Problem responses?

    • RFC 9457 states that extension fields should be added per problem type.
    • If you need to extend HTTP Problem globally (not per type), consider using headers (for metadata) or proposing a design change to this ADP.
  • How should clients handle HTTP Problem?

    • Clients SHOULD process the problem by its type field.
    • Clients SHOULD ignore any unknown or unknown format fields.
  • Which fields are required?

    • RFC 9457 does not explicitly define required/optional fields. The following is our interpretation:
      • You MAY omit detail or even title if type and status are sufficient to describe the problem.
      • type is REQUIRED and the most important field. See ADP-403 for design guidance.
      • status is REQUIRED, used to forward the HTTP status code as part of the error object for error handler chaining.
      • title supplements type. If type is self-explanatory, title can be omitted. If content negotiation is supported, title SHOULD be localized.
      • detail SHOULD provide the user with actionable guidance in plain language, and support localization if Accept-Language is used.
        • detail is less important than title. If present, it should focus on resolution steps.
      • instance is not explicitly required by RFC 9457, but is commonly defined as the relative API path where the problem occurred.

        INFO

        In the absence of a clear standard, we recommend defining instance as the relative API path that triggered the problem.

  • Multilingual support?

    • If your API supports Accept-Language, detail SHOULD be localized. Regardless, if detail is present, you SHOULD specify Content-Language.

Structure of Error Responses

Example error response:

http
HTTP/1.1 500 Internal Server Error
Content-Type: application/problem+json

{
    "type": "/problems/predefined-type",
    "status": 500,
    "title": "A brief human-readable error description",
    "instance": "/items/12345",
    "detail": "Guidance for the user on how to fix the problem"
}

The basic structure of an error response:

PropertyDescriptionRequiredExample
type (string, uri-reference)Must be a URI (Hint 1)Yes/problems/{problem-type}
title (string)A brief, human-readable summary of the problem typeYes"Validation Error"
status (integer)The HTTP status code generated by the original server for this problem instanceYes400
detail (string)A human-readable explanation specific to this problem instance (Hint 2)No"The provided input is invalid, please provide the correct format."
instance (string, uri-reference)A URI reference that identifies the specific instance of the problemNo"/shop-items/123456"

Hint 1

Ideally, this should point to a real website to provide more information about the type, as suggested by RFC.

If you cannot provide an absolute URI when introducing a problem type, using a relative URI is acceptable, e.g., /problems/invalid-input.

Hint 2 About ProblemJSON.detail

  • If sufficient information is already present in other properties, detail MAY be empty.
  • detail should provide users with guidance on how to fix the problem. It SHOULD use plain English (or another language if your API supports Accept-Language), as defined in RFC9457.
  • The difference between detail and title: title is a general brief description, while detail gives specific instructions for resolution.
  • If your API supports Accept-Language, detail may be multilingual. If detail is present, you SHOULD specify Content-Language.

Design Considerations

Many websites use custom error systems to describe custom errors beyond HTTP status codes, such as additional numeric codes. However, users still need to look up the meaning of the codes on the internet, as there is no standard across different applications.

401 Unauthorized Examples

Here are standard HTTP Problem JSON examples for 401 Unauthorized errors:

Basic Example

json
{
  "type": "/problems/unauthorized",
  "title": "Unauthorized access",
  "status": 401,
  "detail": "You must log in to access this resource."
}

With Localization and Instance

json
{
  "type": "https://example.com/problems/unauthorized",
  "title": "Unauthorized access",
  "status": 401,
  "detail": "Please log in to your account and try again.",
  "instance": "/orders/123456"
}

Advanced Example

json
{
  "type": "https://example.com/problems/unauthorized",
  "title": "Unauthorized access",
  "status": 401,
  "detail": "Access token expired, please re-authenticate to obtain a new token.",
  "instance": "/api/v1/profile"
}

References

Standard References

Design References