Search code examples
httperror-handlinghttp-status-codeshttp-status-code-400

When should an API throw a 4xx status code (error) and when a 5xx?


This is a theoretical question. I believe I know the answer but I've received contradicting answers, so I figured I'd ask here.

On the W3C site it says:

Client Error 4xx The 4xx class of status code is intended for cases in which the client seems to have erred.

It also says

Server Error 5xx Response status codes beginning with the digit "5" indicate cases in which the server is aware that it has erred or is incapable of performing the request.

I take this to mean that if a request is syntactically correct, but logically wrong, such as an attempt to create an object with an invalid value on a specific property, then my API should throw a 5xx Error, because the server DID understand the request, but found it to be invalid. I have, on the other hand, been told that it should be a 4xx error (specifically 400 Bad Request) because the logical error was on the client side, as it sent an invalid value in the first place.

So, what error code SHOULD I be reporting?


Solution

  • 5xx error will occur when the problem is on the server side. For example when you make a request with a method or protocol which is not understood by the server, when the proxy did not respond, etc. Per short: when the server was unable to fulfill the request.

    In your example a 4xx error is more appropriate, because the request initiator is the source of the problem. More specific, "422 Unprocessable Entity" error is appropriate, because as RFC 4918 states:

    The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions.

    From various reasons some API designers are trying to limit themselves to a set of 3 - 5 status codes that will be used. In general this is done to ease the work for the API users, which sounds good, but sometimes this philosophy can have bigger implications.

    For example, if I send a request to some API to add a new comment, I would expect a few things to be granted, like (but not limited to):

    • The request is POST or send me back a 405 status if not.
    • If the comment was added I will get back 201 response with a link to my new comment in the body.

    What do I get sometimes ?

    • If the request method is not POST, I will get a 400 error.
    • If the request is POST, I will get back a 200 status and sometimes no link to my new comment.

    Sounds confusing ? For me it does.