RFC 7807
Problem Details for HTTP APIs
0. Title Block Tea βπ
Okay bestie, let's get this tea spilled before we get into the good stuff π . This RFC is RFC 7807: Problem Details for HTTP APIs π¦, written by M. Nottingham (Akamai) and E. Wilde π«Ά. It's a Standards Track document, published in March 2016, and its ISSN is 2070-1721 πΈ. It doesn't obsolete or update any other RFCs, so it's giving fresh start energy β¨.
1. Introduction π
Okay so, HTTP [RFC7230] status codes are sometimes just not enough to explain what went wrong, and that's lowkey a problem π. A human on a web browser can get an explanation in an HTML [W3C.REC-html5-20141028] response body, but non-human consumers of so-called "HTTP APIs" usually can't, and that's the whole gap we're fixing π₯.
This spec defines simple JSON [RFC7159] and XML [W3C.REC-xml-20081126] document formats for exactly this purpose π§. They're built to be reused by HTTP APIs, which can name their own distinct "problem types" based on what they need π.
So API clients can get both the high-level error class (from the status code) and the finer-grained details of the problem (from one of these formats) β¨. Iconic combo, no cap π.
Let's say a response tells the client that their account doesn't have enough credit πΈ. The 403 Forbidden status code might be deemed most appropriate, because it tells HTTP-generic software (like client libraries, caches, and proxies) the general meaning of the response π.
But that doesn't tell the API client enough about why the request was forbidden, what the account balance is, or how to fix it π. If those details go in the response body in a machine-readable format, the client can handle it properly, like triggering a transfer of more credit into the account π. Main character energy for real π¦.
This spec does that by identifying a specific type of problem (like "out of credit") with a URI [RFC3986] πΈ. HTTP APIs can either nominate new URIs under their control, or reuse existing ones π.
Problem details can also include other info, like a URI that identifies the specific occurrence of the problem (basically giving an ID to "The time Joe didn't have enough credit last Thursday" π). That's super useful for support or forensic purposes π΅οΈ.
The data model for problem details is a JSON [RFC7159] object. When it's formatted as a JSON document, it uses the "application/problem+json" media type β¨. Appendix A explains how to express them in an equivalent XML format, which uses the "application/problem+xml" media type π.
Note that problem details are (naturally) not the only way to convey the details of a problem in HTTP π. If the response is still a representation of a resource, for example, it's often better to describe the relevant details in that application's own format π«Ά. And in lots of situations, there's already an appropriate HTTP status code that doesn't need extra detail π .
So the aim of this spec is to define common error formats for the applications that need one π. That way they don't have to define their own, or worse, get tempted to redefine what existing HTTP status codes mean π. Even if an application chooses not to use it for errors, looking at its design can still help guide error-format decisions in an existing format π§.
2. Requirements πΈ
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] π₯.
3. The Problem Details JSON Object π
The canonical model for problem details is a JSON [RFC7159] object π¦.
When it's serialized as a JSON document, that format is identified with the "application/problem+json" media type π.
Here's an example of an HTTP response carrying JSON problem details π:
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"]
}
Here, the out-of-credit problem (identified by its type URI) gives the reason for the 403 in "title" β¨, gives a reference for the specific occurrence of the problem with "instance" π΅οΈ, gives occurrence-specific details in "detail" π, and adds two extensions π. "balance" conveys the account's balance, and "accounts" gives links where the account can be topped up πΈ.
The ability to convey problem-specific extensions lets you convey more than one problem π. For example:
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
Content-Language: en
{
"type": "https://example.net/validation-error",
"title": "Your request parameters didn't validate.",
"invalid-params": [ {
"name": "age",
"reason": "must be a positive integer"
},
{
"name": "color",
"reason": "must be 'green', 'red' or 'blue'"}
]
}
Note that this requires each of the subproblems to be similar enough to use the same HTTP status code π. If they aren't, the 207 (Multi-Status) [RFC4918] code could be used to encapsulate multiple status messages π«Ά.
3.1. Members of a Problem Details Object π
A problem details object can have the following members π :
- "type" (string) - A URI reference [RFC3986] that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type (for example, using HTML [W3C.REC-html5-20141028]) πΈ. When this member is not present, its value is assumed to be "about:blank" π§.
- "title" (string) - A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (for example, using proactive content negotiation; see [RFC7231], Section 3.4) π.
- "status" (number) - The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem π₯.
- "detail" (string) - A human-readable explanation specific to this occurrence of the problem π¦.
- "instance" (string) - A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced π.
Consumers MUST use the "type" string as the primary identifier for the problem type π. The "title" string is advisory and only included for users who aren't aware of the semantics of the URI and can't discover them (for example, during offline log analysis) π΅οΈ. Consumers SHOULD NOT automatically dereference the type URI π .
The "status" member, if present, is only advisory π . It conveys the HTTP status code used for the convenience of the consumer. Generators MUST use the same status code in the actual HTTP response, so that generic HTTP software that doesn't understand this format still behaves correctly π. See Section 5 for further caveats about using it β.
Consumers can use the status member to figure out the original status code the generator used, in cases where it has been changed (for example, by an intermediary or cache), and when message bodies persist without HTTP information πΈ. Generic HTTP software will still use the HTTP status code π§.
The "detail" member, if present, ought to focus on helping the client correct the problem, rather than giving debugging information π.
Consumers SHOULD NOT parse the "detail" member for information π«Ά. Extensions are a more suitable and less error-prone way to get that info π.
Note that both "type" and "instance" accept relative URIs π¦. That means they must be resolved relative to the document's base URI, as per [RFC3986], Section 5 β¨.
3.2. Extension Members π
Problem type definitions MAY extend the problem details object with additional members π.
For example, our "out of credit" problem above defines two such extensions, "balance" and "accounts", to convey additional, problem-specific information πΈ.
Clients consuming problem details MUST ignore any such extensions that they don't recognize π. This lets problem types evolve and include additional information in the future π₯.
Note that because extensions are effectively put into a namespace by the problem type, it's not possible to define new "standard" members without defining a new media type π.
Part 1 of 3 done, bestie π. Part 2 is coming up next, so stay tuned ππ§
4. Defining New Problem Types β¨
Okay so, when an HTTP API needs to send back a response saying something went wrong, it might make sense to define a brand new problem type π
But bestie, before you do that, you need to know what problem types are actually good for, and what's better handled some other way π§
Problem details are not a debugging tool for the underlying implementation π They're a way to expose more detail about the HTTP interface itself. If you're designing new problem types, you have to really think hard about the Security Considerations (Section 5), especially the risk of exposing attack vectors by leaking implementation internals through error messages. Not okay, no cap π
Likewise, truly generic problems (aka conditions that could apply to literally any resource on the Web) are usually better expressed as plain status codes. Like, a "write access disallowed" problem is probably unnecessary, since a 403 Forbidden status code in response to a PUT request is already self-explanatory π
Finally, an application might already have a better way to carry an error in a format it already defines. Problem details are meant to avoid the need to invent new "fault" or "error" document formats, not to replace existing domain-specific formats π«Ά
That said, you can totally add support for problem details to an existing HTTP API using HTTP content negotiation (e.g., using the Accept request header to say you'd prefer this format; see [RFC7231], Section 5.3.2) πΈ
New problem type definitions MUST document:
- a type URI (typically, with the
httporhttpsscheme), - a title that appropriately describes it (think short), and
- the HTTP status code for it to be used with.
Problem type definitions MAY specify the use of the Retry-After response header ([RFC7231], Section 7.1.3) in appropriate circumstances π¦
A problem's type URI SHOULD resolve to HTML [W3C.REC-html5-20141028] documentation that explains how to resolve the problem π
A problem type definition MAY specify additional members on the problem details object. For example, an extension might use typed links [RFC5988] to another resource that can be used by machines to resolve the problem β¨
If such additional members are defined, their names SHOULD start with a letter (ALPHA, as per [RFC5234], Appendix B.1) and SHOULD consist of characters from ALPHA, DIGIT ([RFC5234], Appendix B.1), and "_" (so that it can be serialized in formats other than JSON), and they SHOULD be three characters or longer. The vibe is clean, consistent names that work everywhere π
4.1. Example
Let's say you're publishing an HTTP API for your online shopping cart. You might need to indicate that the user is out of credit (our example from above), and therefore cannot make the purchase π
If you already have an application-specific format that can hold this information, it's probably best to just use that. But if you don't, you might consider using one of the problem details formats: JSON if your API is JSON-based, or XML if it uses that format π
To do so, look for an already-defined type URI that suits your purposes. If one is available, you can reuse it π
If one isn't available, you could mint and document a new type URI (which ought to be under your control and stable over time), plus an appropriate title and the HTTP status code it will be used with, along with what it means and how it should be handled π§
In summary: an instance URI will always identify a specific occurrence of a problem. On the other hand, type URIs can be reused if an appropriate description of a problem type is already available someplace else, or they can be created for new problem types. Main character energy for URIs, honestly π
4.2. Predefined Problem Types
This specification reserves the use of one URI as a problem type:
The "about:blank" URI [RFC6694], when used as a problem type, indicates that the problem has no additional semantics beyond that of the HTTP status code. Just the status code, nothing extra π€
When "about:blank" is used, the title SHOULD be the same as the recommended HTTP status phrase for that code (e.g., "Not Found" for 404, and so on), although it MAY be localized to suit client preferences (expressed with the Accept-Language request header) π
Please note that according to how the "type" member is defined (Section 3.1), the "about:blank" URI is the default value for that member. Consequently, any problem details object not carrying an explicit "type" member implicitly uses this URI π«§
5. Security Considerations π
Okay, this section is serious, so listen up π¨
When defining a new problem type, the information included must be carefully vetted. Likewise, when actually generating a problem (however it is serialized), the details given must also be scrutinized π΅οΈββοΈ
Risks include leaking information that can be exploited to compromise the system, access to the system, or the privacy of users of the system. That's a lot of danger, bestie π
Generators providing links to occurrence information are encouraged to avoid making implementation details such as a stack dump available through the HTTP interface, since this can expose sensitive details of the server implementation, its data, and so on. No stack dumps on the public internet, please π ββοΈ
The "status" member duplicates the information available in the HTTP status code itself, thereby bringing the possibility of disagreement between the two. Their relative precedence is not clear, since a disagreement might indicate that (for example) an intermediary has modified the HTTP status code in transit (e.g., by a proxy or cache). Two sources of truth is giving chaos π
As such, those defining problem types as well as generators and consumers of problems need to be aware that generic software (such as proxies, load balancers, firewalls, and virus scanners) is unlikely to know of or respect the status code conveyed in this member. So double-check, periodt π
6. IANA Considerations π
This specification defines two new Internet media types [RFC6838]. Two new media types, very exciting π
6.1. application/problem+json
Here's the registration template for the JSON one, copied exactly as written:
Type name: application
Subtype name: problem+json
Required parameters: None
Optional parameters: None; unrecognized parameters should be ignored
Encoding considerations: Same as [RFC7159]
Security considerations: see Section 5 of this document
Interoperability considerations: None
Published specification: RFC 7807 (this document)
Applications that use this media type: HTTP
Fragment identifier considerations: Same as for application/json
([RFC7159])
Additional information:
Deprecated alias names for this type: n/a
Magic number(s): n/a
File extension(s): n/a
Macintosh file type code(s): n/a
Person and email address to contact for further information:
Mark Nottingham <mnot@mnot.net>
Intended usage: COMMON
Restrictions on usage: None.
Author: Mark Nottingham <mnot@mnot.net>
Change controller: IESG
6.2. application/problem+xml
And here's the one for XML, also verbatim π§Ύ
Type name: application
Subtype name: problem+xml
Required parameters: None
Optional parameters: None; unrecognized parameters should be ignored
Encoding considerations: Same as [RFC7303]
Security considerations: see Section 5 of this document
Interoperability considerations: None
Published specification: RFC 7807 (this document)
Applications that use this media type: HTTP
Fragment identifier considerations: Same as for application/xml (as
specified by Section 5 of [RFC7303])
Additional information:
Deprecated alias names for this type: n/a
Magic number(s): n/a
File extension(s): n/a
Macintosh file type code(s): n/a
Person and email address to contact for further information:
Mark Nottingham <mnot@mnot.net>
Intended usage: COMMON
Restrictions on usage: None.
Author: Mark Nottingham <mnot@mnot.net>
Change controller: IESG
7. References π
Every single reference, with all its details, so nothing gets lost π«Ά
7.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<http://www.rfc-editor.org/info/rfc2119>.
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66,
RFC 3986, DOI 10.17487/RFC3986, January 2005,
<http://www.rfc-editor.org/info/rfc3986>.
[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234,
DOI 10.17487/RFC5234, January 2008,
<http://www.rfc-editor.org/info/rfc5234>.
[RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March
2014, <http://www.rfc-editor.org/info/rfc7159>.
[RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Message Syntax and Routing",
RFC 7230, DOI 10.17487/RFC7230, June 2014,
<http://www.rfc-editor.org/info/rfc7230>.
[RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Semantics and Content", RFC 7231,
DOI 10.17487/RFC7231, June 2014,
<http://www.rfc-editor.org/info/rfc7231>.
[W3C.REC-xml-20081126]
Bray, T., Paoli, J., Sperberg-McQueen, M., Maler, E., and
F. Yergeau, "Extensible Markup Language (XML) 1.0 (Fifth
Edition)", W3C Recommendation REC-xml-20081126, November
2008, <http://www.w3.org/TR/2008/REC-xml-20081126>.
7.2. Informative References
[ISO-19757-2]
International Organization for Standardization,
"Information Technology --- Document Schema Definition
Languages (DSDL) --- Part 2: Grammar-based Validation ---
RELAX NG", ISO/IEC 19757-2, 2003.
[RFC4918] Dusseault, L., Ed., "HTTP Extensions for Web Distributed
Authoring and Versioning (WebDAV)", RFC 4918,
DOI 10.17487/RFC4918, June 2007,
<http://www.rfc-editor.org/info/rfc4918>.
[RFC5988] Nottingham, M., "Web Linking", RFC 5988,
DOI 10.17487/RFC5988, October 2010,
<http://www.rfc-editor.org/info/rfc5988>.
[RFC6694] Moonesamy, S., Ed., "The "about" URI Scheme", RFC 6694,
DOI 10.17487/RFC6694, August 2012,
<http://www.rfc-editor.org/info/rfc6694>.
[RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type
Specifications and Registration Procedures", BCP 13,
RFC 6838, DOI 10.17487/RFC6838, January 2013,
<http://www.rfc-editor.org/info/rfc6838>.
[RFC7303] Thompson, H. and C. Lilley, "XML Media Types", RFC 7303,
DOI 10.17487/RFC7303, July 2014,
<http://www.rfc-editor.org/info/rfc7303>.
[W3C.REC-html5-20141028]
Hickson, I., Berjon, R., Faulkner, S., Leithead, T.,
Navara, E., O'Connor, E., and S. Pfeiffer, "HTML5", W3C
Recommendation REC-html5-20141028, October 2014,
<http://www.w3.org/TR/2014/REC-html5-20141028>.
[W3C.REC-rdfa-core-20130822]
Adida, B., Birbeck, M., McCarron, S., and I. Herman, "RDFa
Core 1.1 - Second Edition", W3C Recommendation
REC-rdfa-core-20130822, August 2013,
<http://www.w3.org/TR/2013/REC-rdfa-core-20130822>.
[W3C.REC-xml-stylesheet-20101028]
Clark, J., Pieters, S., and H. Thompson, "Associating
Style Sheets with XML documents 1.0 (Second Edition)", W3C
Recommendation REC-xml-stylesheet-20101028, October 2010,
<http://www.w3.org/TR/2010/REC-xml-stylesheet-20101028>.
Appendix A. HTTP Problems and XML β¨
okay so some HTTP-based APIs are full XML girlies π and use it as their main format. Those APIs can express problem details using the format in this appendix π
The RELAX NG schema [ISO-19757-2] for the XML format is below. Bestie, heads up: this schema is only documentation π. It is not a normative schema that captures every constraint of the XML format. It would also be possible to use other XML schema languages to define a similar set of constraints, depending on what features the chosen schema language has π¦
default namespace ns = "urn:ietf:rfc:7807"
start = problem
problem =
element problem {
( element type { xsd:anyURI }?
& element title { xsd:string }?
& element detail { xsd:string }?
& element status { xsd:positiveInteger }?
& element instance { xsd:anyURI }? ),
anyNsElement
}
anyNsElement =
( element ns:* { anyNsElement | text }
| attribute * { text })*
The media type for this format is "application/problem+xml" π
Extension arrays and objects get turned into the XML format like this: an element with a child or children counts as an object, except when the element only contains child elements named i. Those count as arrays πΈ For example, the example above shows up in XML like so:
HTTP/1.1 403 Forbidden
Content-Type: application/problem+xml
Content-Language: en
<?xml version="1.0" encoding="UTF-8"?>
<problem xmlns="urn:ietf:rfc:7807">
<type>https://example.com/probs/out-of-credit</type>
<title>You do not have enough credit.</title>
<detail>Your current balance is 30, but that costs 50.</detail>
<instance>https://example.net/account/12345/msgs/abc</instance>
<balance>30</balance>
<accounts>
<i>https://example.net/account/12345</i>
<i>https://example.net/account/67890</i>
</accounts>
</problem>
Okay, the namespace part is important π This format uses an XML namespace, mainly so it can get embedded into other XML-based formats. It does NOT mean you can or should add elements or attributes from other namespaces. The RELAX NG schema only allows elements from the one namespace used in the format. Any extension arrays and objects MUST be serialized into XML markup using only that namespace β οΈ
When you're using the XML format, you can embed an XML processing instruction that tells clients to transform the XML using the referenced XSLT code [W3C.REC-xml-stylesheet-20101028]. If that code transforms the XML into (X)HTML, then you can serve the XML format and still have clients that can do the transformation show a human-friendly (X)HTML page that gets rendered and displayed on the client π Just a tip from the spec: it's advisable to use XSLT 1.0 so that as many clients as possible can run your XSLT code π§
Appendix B. Using Problem Details with Other Formats
Sometimes it's a win to embed problem details in formats other than the ones described here π¦ For example, an API that uses HTML [W3C.REC-html5-20141028] might want to express its problem details in HTML too π
You can embed problem details in other formats in one of two ways: by wrapping one of the existing serializations (JSON or XML) inside that format, or by translating the model of a problem detail (as specified in Section 3) into the format's own conventions π
For example, in HTML you could embed a problem by wrapping JSON in a script tag:
<script type="application/problem+json">
{
"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"]
}
</script>
or by inventing a mapping into RDFa [W3C.REC-rdfa-core-20130822].
This specification does not make specific recommendations about embedding problem details in other formats. The right way to do it depends on both the format being used and how that format is applied π«Ά
Acknowledgements
Huge thanks to Jan Algermissen, Subbu Allamaraju, Mike Amundsen, Roy Fielding, Eran Hammer, Sam Johnston, Mike McCall, Julian Reschke, and James Snell for reviewing this specification ππ
Authors' Addresses β¨
Mark Nottingham Akamai
Email: mnot@mnot.net URI: https://www.mnot.net/
Erik Wilde
Email: erik.wilde@dret.net URI: http://dret.net/netdret/
π¦ where this page comes from
- ietf: rfc7807 2016-03
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms