Re: BCP56bis: advice for using status codes in applications

> On 20 Jan 2019, at 8:51 am, Julian Reschke <> wrote:
> On 2019-01-09 06:34, Mark Nottingham wrote:
>> Promoting to a new thread, as suggested.
>> I explored the thinking behind this in a blog post a while back:
>> Julian, do you disagree with that, or just how it's expressed here?
>> ...
> Ok, let's look at that blog post first. I just re-read it twice, and it isn't as far-reaching as the text in bcp6bis. For instance:
>> Beyond that, it’s a mistake to try to map each part of your application “deeply” into HTTP status codes; in most cases the level of granularity you want to be aiming for is much coarser. When in doubt, it’s OK to use the generic status codes 200 OK, 400 Bad Request and 500 Internal Service Error when there isn’t a better fit.
> Note the "when in doubt".

Noted. What meaning are you reading into those three words?

> Later:
>> So You Want To Create a HTTP Status Code
>> If after reading all of that, you still think you need a new status code – it’s something that’s potentially applicable to all resources, it has specific effect on HTTP implementations, there isn’t an existing status code that has that effect, and you’re willing to go through the process, take a look at these guidelines.
> So that is specific to new codes, not using the ones we have.

What you you mean by "that" here?

> So, no, I don't really disagree with that blog post. But that's what bcp56bis says. In particular:

Do you mean that's *not* what bcp56bis says?

>> 4.6. HTTP Status Codes
>> The primary function of a HTTP status code is to convey semantics for the benefit of generic HTTP software, not to convey application-specific semantics.
> But then RFC 7231 just says "The status-code element is a three-digit integer code giving the result of the attempt to understand and satisfy the request." - much broader.
> I disagree with this narrow definition. HTTP after all is an application-level protocol.

Point taken, but the application it was defined for (web browsing) have latent semantics that are sometimes an awkward fit for other applications.

>> Status codes are often generated or overwritten by intermediaries, as well as server and client implementations. This can happen, for example, when network errors are encountered, a captive portal is present, when an implementation is overloaded, or it thinks it is under attack. As a result, the status code that a server-side application generates and the one that the client software receives often differ.
> I think the more likely case is that the request actually did not reach the origin server, so one is really dealing with a non-authoritative answer.

True. I'll adjust that.

>> This means that status codes are not a reliable way to carry application-specific signals. Specifying that a particular status code has a specific meaning in the context of an application can have unintended side effects; if that status code is generated by a generic HTTP component can lead clients to believe that the application is in a state that wasn’t intended.
> But how likely is that for the more specific codes such as 409 or 422 (defined for ages, just recently added to the base spec)?
>> Instead, applications using HTTP should specify the implications of general classes of responses (e.g., “successful response” for 2xx; “client error” for 4xx and “server error” for 5xx), conveying any application-specific information in the message body and/or HTTP header fields, not the status code. [RFC7807] provides one way for applications using HTTP to do so for error conditions.
> This sounds like intermediaries can break the status code, but for some reason can't break the payload.
> (I like adding details to the payload, as per RFC 4918 which IMHO did that first, and later RFC 7807, but that does not necessarily imply that more specific status codes do not make sense as well)
>> There are limited exceptions to this; for example, applications might use 201 (Created) or 404 (Not Found) to convey application semantics that are compatible with the generic HTTP semantics of those status codes. In general, though, applications should resist the temptation to map their semantics into fine-grained status codes.
> I think using fine-grained status codes actually does no harm, except when developers get carried away with that. Thus the "in doubt" in the blog post makes sense.

I think we're in agreement here. Looking at it again, the underlying issue that's most concerning is that developers try to do a 1:1 mapping between their application's errors and status codes, and quickly tie themselves into knots. The advice should address that problem directly.

Take a look at this edit and see if it's better:


> I'll finish with two more thoughts:
> 1) There are limits to using the payload for machine-readable status information -- it doesn't work well when the request was GET and is supposed to make sense in a generic browser, or when it's the result of a classic HTML form POST.

Sorry, can you expand upon this? (Or provide suggested text...)

> 2) Maybe it would worthwhile to discuss the usability of a few concrete status codes, such as 403, 409, or 422.

PRs welcome.


Mark Nottingham

Received on Sunday, 20 January 2019 21:39:56 UTC