O'Reilly logo

RESTful Web Services by Sam Ruby, Leonard Richardson

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

4xx: Client-Side Error

These status codes indicate that something is wrong on the client side. There’s a problem with authentication, with the format of the representation, or with the HTTP library itself. The client needs to fix something on its end.

400 (“Bad Request”)

Importance: High.

This is the generic client-side error status, used when no other 4xx error code is appropriate. It’s commonly used when the client submits a representation along with a PUT or POST request, and the representation is in the right format, but it doesn’t make any sense.

Entity-body: May contain a document describing why the server thinks there’s a client-side error.

401 (“Unauthorized”)

Importance: High.

The client tried to operate on a protected resource without providing the proper authentication credentials. It may have provided the wrong credentials, or none at all. The credentials may be a username and password, an API key, or an authentication token—whatever the service in question is expecting. It’s common for a client to make a request for a URI and accept a 401 just so it knows what kind of credentials to send and in what format. In fact, the HTTP Digest mode of authentication depends on this behavior.

If the server doesn’t want to acknowledge the existence of the resource to unauthorized users, it may lie and send a 404 (“Not Found”) instead of a 401. The downside of this is that clients need to know, in advance, what kind of authentication the server expects for that resource: things like HTTP Digest won’t work.

Response headers: The WWW-Authenticate header describes what kind of authentication the server will accept.

Entity-body: A document describing the failure: why the credentials (if any were provided) were rejected, and what credentials would be accepted. If the end user can get credentials by signing up on a web site, or creating a “user account” resource, a link to the sign up URI is useful.

402 (“Payment Required”)

Importance: None.

Apart from its name, this status code is not defined in the HTTP standard: it’s “reserved for future use.” This is because there’s no micropayment system for HTTP. That said, if there ever is a micropayment system for HTTP, web services are among the first places that system will start showing up. If you want to charge your users by the web service request, and your relationship with them makes that possible, you might have a use for this status code. But note that Amazon S3 doesn’t use this status code, and it charges by the request just fine.

403 (“Forbidden”)

Importance: Medium.

The client’s request is formed correctly, but the server doesn’t want to carry it out. This is not merely a case of insufficient credentials: that would be 401 (“Unauthorized”). This is more like a resource that is only accessible at certain times, or from certain IP addresses.

A response of 403 implies that the client requested a resource that really exists. As with 401 (“Unauthorized”), if the server doesn’t want to give out even this information, it can lie and send a 404 (“Not Found”) instead.

If the client’s request is well-formed, why is this status code in the 4xx series (client-side error) instead of the 5xx series (server-side error)? Because the server made its decision based on some aspect of the request other than its form: say, the time of day the request was made.

Entity-body: Optionally, a document describing why the request was denied.

404 (“Not Found”)

Importance: High.

Probably the most famous HTTP status code. 404 indicates that the server can’t map the client’s URI to a resource. Compare 410 (“Gone”), which is slightly more helpful. A web service may use a 404 response as a signal to the client that the URI is “free”; the client can then create a new resource by sending a PUT request to that URI.

Remember that a 404 may be a lie to cover up a 403 or 401. It might be that the resource exists, but the server doesn’t want to let the client know about it.

405 (“Method Not Allowed”)

Importance: Medium.

The client tried to use an HTTP method that this resource doesn’t support. For instance, a read-only resource may support only GET and HEAD. Another resource may allow GET and POST, but not PUT or DELETE.

Response headers: The Allow header lists the HTTP methods that this resource does support. The following is a sample header:

Allow: GET, POST

406 (“Not Acceptable”)

Importance: Medium.

The server may send this response code when the client places so many restrictions on what it considers an acceptable representation (probably using the Accept-* request headers) that the server can’t send any representation at all. The server may instead choose to ignore the client’s pickiness, and simply send its preferred representation along with a response code of 200 (“OK”). This is usually what happens on the human web.

Entity-body: A list of links to acceptable representations, in a format similar to that described in 300 (“Multiple Choices”).

407 (“Proxy Authentication Required”)

Importance: Low.

You’ll only see this status code from an HTTP proxy. It’s just like 401 (“Unauthorized”), except the problem is not that you can’t use the web service without credentials: it’s that you can’t use the proxy without credentials. As with 401, the problem may be that the client provided no credentials, or that the credentials provided are bad or insufficient.

Request headers: To send credentials to the proxy, the client uses the Proxy-Authorization header instead of the Authorization header. The format is identical to that of Authorization.

Response headers: Instead of the Authenticate header, the proxy fills the Proxy-Authenticate header with information about what kind of authentication it expects. The format is identical to that of Authenticate.

Note that both the proxy and the web service may require credentials, so the client may clear up a 407 only to be hit with a 401 (“Unauthorized”).

408 (“Request Timeout”)

Importance: Low.

If an HTTP client opens a connection to the server, but never sends a request (or never sends the blank line that signals the end of the request), the server should eventually send a 408 response code and close the connection.

409 (“Conflict”)

Importance: High.

Getting this response code means that you tried to put the server’s resources into an impossible or inconsistent state. Amazon S3 gives this response code when you try to delete a bucket that’s not empty. My bookmarking service gives it when you try to change your username to a name that’s already taken.

Response headers: If the conflict is caused by the existence of some other resource (such as when you try to change your username to a name that’s taken), the Location header should point to the URI of that resource: that is, the source of the conflict.

Entity-body: Should contain a document that describes the conflicts, so that the client can resolve them if possible.

410 (“Gone”)

Importance: Medium.

This response code is like 404 (“Not Found”), but it provides a little more information. It’s used when the server knows that the requested URI used to refer to a resource, but no longer does. The server doesn’t know any new URI for the resource; if it did, it would send a 301 (“Permanent Redirect”).

Like the permanent redirect, a 410 response code has the implication that the client should remove the current URI from its vocabulary, and stop making requests for it. Unlike the permanent redirect, the 410 offers no replacement for the bad URI: It’s just gone. RFC 2616 suggests using a 410 response code “for limited-time, promotional services and for resources belonging to individuals no longer working at the server’s site.”

You might be tempted to send this response code in response to a successful DELETE request, but that’s a little too cute. The client wouldn’t know whether it deleted the resource or whether it was gone before it made their request. The correct response to a successful DELETE request is 200 (“OK”).

411 (“Length Required”)

Importance: Low to medium.

An HTTP request that includes a representation should set the Content-Length request header to the length (in bytes) of the representation. Sometimes this is inconvenient for the client: for instance, when the representation is being streamed from some other source. So HTTP doesn’t require a client to send the Content-Length header with each request. However, the HTTP server is within its rights to require it for any given request. The server is allowed to interrupt any request that starts sending a representation without having provided a Content-Length, and demand that the client resubmit the request with a Content-Length header. This is the response code that goes along with the interruption.

If the client lies about the length, or otherwise sends too large a representation, the server may interrupt it and close the connection, but in that case the response code is 413 (“Request Entity Too Large”).

412 (“Precondition Failed”)

Importance: Medium.

The client specified one or more preconditions in its request headers, effectively telling the server to carry out its request only if certain conditions were met. Those conditions were in fact not met, so instead of carrying out the request the server sends this status code.

A common precondition is If-Unmodified-Since. The client may PUT a request to modify a resource, but ask that the changes take effect only if no one else has modified the resource since the client last fetched it. Without the precondition, the client might overwrite someone else’s changes without realizing it, or might cause a 409 (“Conflict”).

Request headers: The client might get this response code by using any of the If-Match, If-None-Match, or If-Unmodified-Since headers.

If-None-Match is a bit special. If the client specifies If-None-Match when making a GET or HEAD request, and the precondition fails, then the response code is not 412 but 304 (“Not Modified”). This is the basis of conditional HTTP GET. If a PUT, POST, or DELETE request uses If-None-Match, and the precondition fails, then the response code is 412. The response code is also 412 when a precondition uses the If-Match or If-Unmodified-Since headers, no matter what the HTTP method is.

413 (“Request Entity Too Large”)

Importance: Low to medium.

This is similar to 411 (“Length Required”) in that the server can interrupt the client’s request with this status code, and close the connection without waiting for the request to complete. The 411 status code was for requests that didn’t specify the length of their representation. This status code is for requests that send a representation that’s too large for the server to handle.

A look-before-you-leap request (see Chapter 8) is the best way for a client to avoid being interrupted with this error. If the LBYL request gets a response code of 100 (“Continue”), the client can go ahead and submit the full representation.

Response headers: The problem may be temporary and on the server side (a lack of resources) rather than on the client side (the representation is just too damn big). If so, the server may set the Retry-After header to a date or a number of seconds, and the client can retry its request later.

414 (“Request-URI Too Long”)

Importance: Low.

The HTTP standard imposes no official limit on the length of a URI (and, in my opinion, there shouldn’t be any). However, most existing web servers impose an upper limit on the length of a URI, and a web service may do the same. The most common cause is a client putting representation data in the URI, when it should be in the entity-body. Deeply-nested data structures can also cause very long URIs.

415 (“Unsupported Media Type”)

Importance: Medium.

The server sends this status code when the client sends a representation in a media type it doesn’t understand. The server might have been expecting XML and the client sent JSON.

If the client sends a document that’s got the right media type but the wrong format (such as an XML document written in the wrong vocabulary), a better response is the more generic 400 (“Bad Request”). That’s what I use throughout my bookmark service. If you really want to treat that case specially, you can send the WebDAV extended response code 422 (“Unprocessable Entity”).

416 (“Requested Range Not Satisfiable”)

Importance: Low.

The server sends this status code when the client asks for a series of byte-ranges from a representation, but the representation is actually too small for any of the byte-ranges to apply. In other words, if you ask for byte 100 of a 99-byte representation, you’ll get this status code.

Request headers: This status code will only be sent when the original request included the Range header request field. It will not be sent if the original request included the If-Range header request field;

Response headers: The server should send a Content-Range field that tells the client the actual size of the representation.

417 (“Expectation Failed”)

Importance: Medium, but (as of time of writing) rarely used.

This response code is the flip side of 100 (“Continue”). If you make a LBYL request to see whether the server will accept your representation, and the server decides it will, you get a response code 100 and you can go ahead. If the server decides it won’t accept your representation, you get a response code 417, and you shouldn’t bother sending your representation.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required