HTTP Error Handling

Originally heavily plagierized from a DZone article I read, but it's not only that article's content...

Why status codes matter...

  1. Clients (of servers) already (or can be easily extended to) handle different codes with special behavior such as...
    • 301 Moved Permanently versus 302 Found
    • 301 Moved Permanently is implictly cachable while 429 Too Many Requests isn't
    • a client library could handle 429 Too Many Requests by backing off and retrying after a delay.
    • a client library could similarly handle 503 Service Unavailable
  2. Though not exhaustive for modern requirements, many status code represent cases still worth handling with a special response.
    • APIs returning 404 in place of 405 Method Not Allowed beg the question, "What the URL merely fat-fingered or is the request using the wrong HTTP method?
    • Hours of debugging could be saved by returning 502 Bad Gateway in place of 500 Internal Server Error.
  3. A convention has been in the establishment among widely used APIs of using status codes like 201 Created, 429 Too Many Requests and 503 Service Unavailable. Following these conventions, a site's API would be more easily troubleshot.

Follow the HTTP Rules

Follow HTTP expectations:

  1. Provide the correct status code.
  2. Honor the Accept statement in the header.
  3. Send the correct Content-Type in the header.

Status code

There are two acceptable ranges of status code for an error response: 4xx or 5xx.

The 4xx range is for client-side errors and the 5xx for server side. In general, a 4xx means that the client needs to do something before it tries again. Some like 401 and 403 are related to permissions while most are related to ensuring that the message is a good HTTP message. Use 400 for validation errors.

Nearly all the 5xx are infrastructure related, so in code, a 500 or 503 will be most likely returned if something goes wrong at the server end. If 503, add the Retry-After statement to the header so clients won't hammer the server. Here are two examples:

Retry-After: Fri, 31 Dec 1999 23:59:59 GMT               (means not before this date and time)

Retry-After: 120                                         (means not for 2 minutes)

Accept (and Content-Type) in header

The Accept statement is used by HTTP clients to tell the server what content types they'll accept. The server returns a header with a Content-Type statement saying what the actual content type of the response is. (And this should be what the client passed in Accept if at all possible.)

An error response should honor the data format indicated by the client in the Accept header sent. If it says XML, don't return JSON or HTML. Some examples:

Accept: text/plain

Accept: application/xml

Accept: application/json

Accept-Charset: utf-8

Accept-Encoding: gzip, deflate

Similarly, ensure that the correct Content-Type header gets set describing the response for the client to use this when decoding it.

Content-Type: application/xml

Content-Type: application/json

If using a standard media type for the error, then save on documentation and allow client to use a library to handle it. If using a media type with error objects defined (e.g.: JSON-API), use that.

Otherwise, use RFC7807: Problem Details for HTTP APIs. This defines both a JSON and XML format for error handling and there are libraries out there for most languages that will decode it.

In documentation, encourage clients to use an Accept header that names all the media types the server is expected to return. e.g.:

Accept: application/hal+json, application/problem+json

ContentType in header

The error response message should, at a minimum, provide two bits of information:

The code is for the client application. It should never change and allows the client to perform different actions based on the specific error returned. An application error code is required because HTTP status codes are too little granular and a client should never have to string match to work out what's going on.

The human readable error message is to help client developers as much as possible. The message should provide information on what's gone wrong and ideally give information on how to fix it.

Document all codes and messages.



Cool article by Pragati Verma, uncommon HTTP status codes

HTTP status codes that we don't use that commonly, but they can have fascinating use cases. I copied the essential content here in case this URL is ever lost.

103 Early Hints

The 103 Early Hints HTTP status code is a bit unusual but pretty interesting. It's like a friendly advance notice from a web server to your browser. When a server sends a 103 code, it's saying, "Hey, I'm going to send you a bunch of stuff, and here's a sneak peek to get you started."

It's kind of like when you're at a restaurant, and the chef sends out a little appetizer before your main course. In this case, the server is letting your browser know that more data is on the way, so your browser can start preparing to receive it. It's all about optimizing the loading process and making your web experience smoother.

Its benefits include:

300 Multiple Choices

The HTTP status code 300, "Multiple Choices," is used to indicate that the requested resource has multiple representations available, each with its own specific location (URI), and the user or client must choose one.

When a server returns a 300 status code, it typically includes a "Location" header in the response with a list of URIs for the alternative representations of the resource. The client can then decide which URI to follow based on user preferences or application logic.

For example, if a client requests a resource like a document, and the server has multiple versions of that document in different formats (e.g., HTML, PDF, plain text), it can respond with a 300 status code and provide URIs for each version. The client can then prompt the user to choose the preferred format, or it can use its own logic to make the selection.

The 300 status code is relatively rare in typical web interactions and is mainly used in scenarios where content negotiation is necessary to determine the best representation of a resource based on user or application requirements.

303 See Other

The HTTP status code 303 See Other is a redirection status code used to instruct a web client (usually a web browser) to perform a GET request to a different URI. It indicates that the resource the client requested can be found at a different location, and the client should retrieve it from there.

This status code is like a signpost that says, "You asked for something, but it's not here. Go check somewhere else!" It's a way for a web server to tell your browser that the resource you're looking for can be found at a different location or URL.

Wait, doesn't that sound a lot like HTTP status code 302 Found?

HTTP status codes 302 and 303 both deal with redirection, but they serve different purposes. The key distinction lies in the nature of the redirection. The 302 status code indicates a temporary redirection, where the requested resource is temporarily available at a different URI.

In contrast, the 303 status code signifies a more explicit redirection, instructing the client to make a new GET request to the alternative URI for the requested resource.

While 302 implies that future requests may still be directed to the original URI, 303 is often used when you want to ensure that subsequent requests for the same resource always go to the new URI, making it particularly useful for certain web forms and data submissions.

For example, after successfully submitting a form on a website, the server might respond with a 303 code and a "Location" header pointing to a new URI that displays a thank-you message or a confirmation page. This ensures that refreshing the confirmation page won't result in a duplicate form submission. The client is instructed to make a GET request to the new URI to retrieve the result or view the confirmation, decoupling it from the initial POST request.

406 Not Acceptable

The HTTP status code 406 Not Acceptable is returned by a web server when a client's request specifies certain response criteria, such as acceptable media types (content types), languages, or character sets, that the server cannot fulfill based on the available resources. In other words, the server cannot provide a response that matches the client's specified preferences.

For example, if a client sends an HTTP request header indicating that it only accepts responses in a particular language or content type, and the server does not have the requested content in that language or format, it would respond with a 406 status code.

The 406 status code is essentially a way for the server to communicate to the client that it cannot meet the specific content requirements specified in the request, and the client may need to adjust its preferences or handle the situation accordingly, such as by requesting a different content type or language.

Sounds a lot like 404 Not Found no? No, it doesn't, if you read it carefully, the 406 status code is about the server having the resource but not in the requested format, while the 404 status code is about the server not finding the resource at all.

409 Conflict

The HTTP status code 409, "Conflict," is used to indicate that the request could not be completed due to a conflict with the current state of the target resource. This status code typically arises in scenarios involving concurrent updates or conflicting changes to a resource.

For example, if two users attempt to modify the same piece of data simultaneously, a conflict can occur. In this case, the server may respond with a 409 status code to inform the clients that their requests cannot be processed because of the conflicting changes.

The response often includes additional information or guidance on how to resolve the conflict, such as which resource state caused the conflict or how clients can retry their requests after addressing the conflict. It is commonly used in web applications, especially those with collaborative editing or version control features, to manage data consistency in situations where multiple parties can modify the same resource.

Did you think of 400 Bad Request while reading the above case? Well, to clarify that, while a 400 error points to issues with the request itself, a 409 error points to conflicts arising from the state of the resource being modified.

410 Gone

The HTTP status code 410, "Gone," is used to indicate that a previously available resource on the server is no longer accessible and has been intentionally removed or permanently deleted. Unlike the 404 status code, which simply indicates that a resource is not found, the 410 status code explicitly conveys that the resource existed in the past but has now been deliberately taken down, and there is no expectation of it becoming available again in the future.

Website administrators and developers may use the 410 status code when they want to inform both clients and search engines that a resource, such as a webpage or an API endpoint, has been permanently discontinued. This can be useful for maintaining the accuracy of search engine results and informing users that the resource they were seeking is no longer accessible.

417 Expectation Failed

The HTTP status code 417, "Expectation Failed," is used to indicate that a server cannot meet the client's expectations specified in the "Expect" request header of the HTTP request.

The "Expect" header is typically used to define certain expectations the client has about how the server should handle the request, such as requesting that the server respond with a specific status code or comply with certain protocol extensions.

When a server encounters an "Expect" header that it cannot fulfill, it responds with a 417 status code. This can happen, for example, if the client expects the server to support a specific authentication method or protocol extension, but the server cannot meet that expectation.

The 417 status code is relatively rare and may not be encountered in everyday web browsing.

418 I'm a (little) teapot

HTTP status code 418, "I'm a teapot," is an April Fools' joke and is not a standard HTTP status code. It was introduced in RFC 2324, a document titled "Hyper Text Coffee Pot Control Protocol," which is not a serious HTTP specification but rather a humorous and playful one.

This status code was intended to be a joke and not meant for actual use in web development or communication between servers and clients. It is not recognized or implemented by web servers or browsers for practical purposes.

So, if you encounter the "418 I'm a teapot" status code in any context, it's likely being used for fun or as a humorous way to communicate that the request is not valid or should not be taken seriously.

422 Unprocessable Content

You might know about the HTTP status code 400, "Bad Request," which indicates that the server cannot process the client's request due to issues with the request itself, such as malformed syntax or missing required parameters. It signifies that the server does not understand or cannot fulfill the request due to client errors.

On the other hand, HTTP status code 422, "Unprocessable Entity," is used when the server can understand the client's request but cannot process it because the request's content, such as data or input, is semantically incorrect, syntactically invalid, or violates validation rules set by the server. It specifically addresses issues with the request's content, making it a more suitable choice when the request entity is problematic but not due to generic syntax errors.

451 Unavailable For Legal Reasons

The HTTP status code 451, "Unavailable For Legal Reasons," is used to indicate that a server has received a request for a resource, but it refuses to fulfill the request due to legal restrictions or legal censorship.

This status code is typically used when a government or legal authority has mandated the removal or blocking of specific content, and the server must comply with these legal requirements.

The name "451" is a reference to Ray Bradbury's novel "Fahrenheit 451," in which books are banned and burned by the government. The choice of this status code name symbolizes the idea of content being "unavailable for legal reasons."

When a server responds with a 451 status code, it may also include additional information in the response, such as a description of the legal restrictions or a reference to the relevant laws or regulations.

The 451 status code is relatively recent in the HTTP standard and reflects the growing awareness of legal and censorship-related issues on the internet. Its use is typically associated with cases where access to certain online content is restricted due to legal compliance.