406 Not Acceptable

Happy 2019! After a small hiatus we’re back with this captivating series. I hope you’re as excited as I am and I hope you have the best 2019!

406 Not Acceptable is emitted by a server when the client asked for a specific representation of a resource that the server doesn’t support.

Accept headers

HTTP has a feature called content negotation. This feature allows a client to request a specific version of a resource. These are the main relevant request headers:

  • Accept - If a server supports several content-types, a client can use this header to indicate which they prefer. For example, an API might support both JSON and XML.
  • Accept-Charset - To request a specific character set. In 2019 this is not really useful as everything should be UTF-8.
  • Accept-Encoding - Is generically used for clients to indicate what type of compression they support. Gzip has been supported by every browser for a long time. Recently Brotli, a new compression format has popped up. Clients indicate their support for this via the Accept-Encoding header.
  • Accept Language allows a client to indicate which language they prefer. Browsers use this to tell a server which language the user prefers. For example, a browser might tell the server they prefer Dutch 1st, and English second with Accept-Language: nl-NL; q=1, en; q=0.9.
  • A-IM is used to indicate what kind of Instance Manipulation formats it supports. Also see 226 IM Used.

Example

This client is indicating that it prefers to receive application/json in French.

GET /foo HTTP/1.1
Accept: application/json
Accept-Language: fr-CA; q=1, fr; q=0.8 

If the server didn’t support JSON, it might respond with:

HTTP/1.1 406 Not Acceptable
Server: curveball/0.4
Content-Type: text/html

<h1>Je ne support pas application/json</h1>

Huge disclaimer: I only had 2 years of french and it’s over 15 years ago.

Usage

It’s a great idea for APIs to support this for the Accept/Content-Type header. If an API defines specific content-types, they might be easier to evolve. Strictly enforcing the appearance of an Accept header with these specific content-types really helps with this. If a client doesn’t send it, a 406 status should be returned.

Likewise, it can be useful for multi-lingual web applications to support Accept-Language to figure out the user’s preferred language.

References

HTTP series

This article is part of an ongoing series about the HTTP protocol.

If you want to follow along as I write them, you can Subscribe to my Atom feed or Mailing list.

Informational 1xx

Successful 2xx

Redirection 3xx

Client Error 4xx

Web mentions