Communications

A standardized error format for HTTP responses

HTTP uses status codes to indicate the result of the servers attempt to satisfy the request. In case the server is unable to process the request we can choose from a variety of HTTP error codes.

Unfortunately status codes alone often do not provide enough information for API clients. For example, a server might respond with the status code 400 (Bad Request) to indicate the client sent an invalid request. Wouldn’t it be nice if the response body would tell us what specific part of the request was invalid or how to resolve the problem?

Status codes are used to define higher level error classes while error details are usually part of the response body. Many APIs use a custom error format for response bodies to provide additional problem information. However, there is also a standard that can help us here, defined in RFC 2707.

RFC 7807 defines a data model for problem details in JSON and XML. Before coming up with a new generic fault or error response format for you API, it might be worth looking into RFC 7807. However, it is absolutely fine to use your own domain-specific format if this fits better to your application.

RFC 7807: Problem Details for HTTP APIs

A HTTP response using RFC 7807 might look like this:

HTTP/1.1 400 Bad request
Content-Type: application/problem+json
Content-Language: en

{
    "type": "https://api.my-cool-example.com/problems/required-field-missing",
    "title": "Required field is missing",
    "detail": "Article with id 1234 cannot be updated because the required field 'title' is missing",
    "status": 400,
    "instance": "/articles/1234",
    "field": "title"
}

As usual, the HTTP status code (400, Bad request) gives us a broad indication of the problem. Notice the response Content-Type of application/problem+json. This tells us the response contains a RFC 7807 compliant body. When using XML instead of JSON the Content-Type application/problem+xml is used.

A problem details JSON response can have the following members:

  • type (string) – A URI reference that identifies the problem type.
  • title (string) – A short human-readable summary of the problem type. It should not change between multiple occurrences of the same problem type, except for purposes of localization.
  • status (number) – The HTTP status code generated by the origin server.
  • detail (string) – A human-readable description of this specific problem occurrence.
  • instance (string) – A URI that identifies the resource related to this specific problem occurrence.

All fields are optional. However, you should at least provide a type value as this is used by consumers to identify the specific problem type. Consumers should not parse the title or detail fields.

Problem types

Problem types are used to identify specific problems. A problem type must document:

  • A type URI (that is used in the type field of the response).
  • A title that describes the problem (used in the title field of the response).
  • The HTTP status code it is used with.

The type URI should resolve to a human-readable documentation of the problem (e.g. a HTML document). This URI should be under your control and stable over time.

Problem types may also specify the use of a Retry-After response header if appropriate.

RFC 7807 reserves one special URI as a problem type: about:blank. The problem type about:blank can be used if the problem has no additional semantics besides that of the HTTP status code. In this case, the title should be the same as the HTTP status phrase for that code (e.g. Bad Request for HTTP status 400).

Extension members

Problem types may extend the problem details object with additional members to provide additional information.

The field member from the example response shown above is an example of such an extension member. It belongs to the required-field-missing problem type and indicates the missing field. A consumer might parse this member to construct an appropriate error message for the end-user.

Conclusion

HTTP status codes alone are often not enough to provide a meaningful problem description.

RFC 7807 defines a standardized format for a more detailed problem descriptions within the body of an HTTP response. Before coming up with just another custom error response format, it might be a good idea to look at the RFC 7807 problem format.

Published on Java Code Geeks with permission by Michael Scharhag, partner at our JCG program. See the original article here: A standardized error format for HTTP responses

Opinions expressed by Java Code Geeks contributors are their own.

Michael Scharhag

Michael Scharhag is a Java Developer, Blogger and technology enthusiast. Particularly interested in Java related technologies including Java EE, Spring, Groovy and Grails.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Steve
2 years ago

More detailed error messages are nice for developers BUT bad for production sites. Detailed error messages in production provide adversaries (“bad actors”) with information that will allow them to more quickly adjust an attack request that failed into a successful attack. For example, if an adversary attempts to access an /admin (or other sensitive) directory and you return a 401 or a 403, the adversary now knows that there is such a directory. And depending on the ddirectory name attempted, may be able to determine that you are using php, or dnn, or other application (you inadvertantly leaked information about… Read more »

Back to top button