[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 be compatible with HTTP Problem.
Error responses MUST be in JSON format.
The Content-Type header of error responses MUST be
application/problem+json
.Existing problem types SHOULD be reused whenever possible:
If additional information is indeed needed, extra fields MAY be added to extend the problem JSON.
http{ "type": "https://example.net/validation-error", "title": "Your request is invalid.", "extraInfo": "...." }
If the problem type cannot be clearly described, consider designing additional types, see ADP-403.
Structure of Error Responses
Example of an error response:
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 should be as follows:
Property | Description | Required | Example |
---|---|---|---|
type (string, uri-reference) | Must be a URI (Hint 1) | Yes | /problems/{problem-type} |
title (string) | A brief, human-readable summary of the problem type | Yes | "Validation Error" |
status (integer) | The HTTP status code generated by the original server for this problem instance | Yes | 400 |
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 problem | No | "/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 we 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. In other words, it should SHOULD use colloquial English (or another language if your API supports Accept-Language), as defined in RFC9457.- The distinction between
detail
andtitle
:title
is a more general brief description of the problem, whiledetail
provides specific instructions for fixing the problem. - If your API supports Accept-Language,
detail
may be multilingual. Regardless of whether you support multiple languages, if there is adetail
field,Content-Language
should be specified.
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.
Examples
Let's take Windows error codes as an example. See https://learn.microsoft.com/zh-tw/windows-hardware/drivers/debugger/bug-check-code-reference2.
Should be done like this:
{
"type": "/problems/ipt-watchdog-timeout",
"status": 500,
"detail": "...."
}
Should not be done like this:
{
"status": "0x0001db"
}