4

Here's the description of 422 Unprocessable Entity:

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. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.

RFC-4918

Does it mean that I must return 400 Bad Request only in case of an incorrect syntax? For example, if a client tries to transfer a negative money amount, syntactically correctly, is 400 wrong? I believed 400 was something of a catch-all response code for all client errors when you can't or don't want to be more specific. Another RFC, 7231, seems to support this view:

The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).

RFC-7231

What's the true scope of 400?

4
  • 1
    "An earlier RFC, 7231" Earlier? Per your links, RFC-7231 is dated June 2014 and RFC-4918 is dated June 2007. Also, 4918 is about WebDav extensions and 7231 is the about HTTP in general. Commented May 30 at 19:39
  • 1
    Also, this obsoletes 7231: datatracker.ietf.org/doc/html/rfc9110 Commented May 30 at 19:40
  • I would say that 400 is the catch-all 4xx error code that you can use when no other, more specific, 4xx status fits. Commented Jun 2 at 12:03
  • To extend Bergi's point, all the X00 statuses are the "plain" ones, whereas more specific XYZ (same X value) are more specific ones. 2 = All good, 4 = You (the caller) messed up, 5 = I (the server) messed up. If you want more detail, use a more granular code. The necessity of doing so and to what degree is highly subjective. Commented Jun 12 at 3:53

2 Answers 2

5

RFC 9110 has the prevailing definition for a 400 Bad Request:

The 400 (Bad Request) status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).

This doesn't really provide concrete guidance about when to use this response code. You must consider the purpose of a given HTTP endpoint when making this decision. For example, ASP.NET responds with a 400 Bad Request for a POST back to the server which is missing an anti-forgery token, or the token passed in the request is invalid. You'll need to judge the intended use of the endpoint against what you believe to be the intent of the client sending the request. If another 4xx response is a better fit, use that. If not, a 400 isn't the worst thing you can respond with.

There is a lot of discretion given to the implementers of an HTTP application to choose a response that best fits the scenario, so choose the one that seems to be most specific while balancing that with client expectations.

I've always interpreted a 400 Bad Request to mean the client messed something up such that I can't process the request, nor can I tell you specifically what was wrong and I can't tell you how to fix it. So don't try it again. Sometimes you might want to be vague for security purposes.

As an example, recently I built an application that requires a form of automatic captcha. The server validates a captcha token before processing the request. I decided that a missing or invalid token should result in a 400 response. Client error. Not my fault. No additional information was given so I'm not giving attackers anything that could be used to try a more effective attack. Leave them guessing.

3
  • "most web servers respond with 400 Bad Request when a client sends a POST request to a URL that only accepts GET" - shouldn't 405 be used for that? Commented Jun 2 at 12:10
  • @Bergi - you are correct. I changed my answer. I had an example in mind and completely missed the mark initially. Commented Jun 2 at 18:54
  • To make things more interesting, RCF7807 (Problem Details) used 400 as an example of validation error details but the RFC9457 that replaces it now uses 422. Commented Jun 3 at 17:12
0

The common example of 422 seems to be sending a "create this thing" when the thing already exists. eg git

The message is perfect and has no flaws, you've already processed it once after all. But it can't be processed this time around due to the semantics of the process.

The different codes exist so you can differentiate the client's response to an error. The client knows that a 400 means a malformed message, something that should not happen. It should send a bug report.

Whereas a 422 means the message format was fine, you are asking for things I can't do. Maybe display something to the user about the process.

These codes get co-opted for non-hypertext uses in APIs, and people just pick the one they think fits best to be RESTful. But if your client library doesn't understand the meaning of the code and take different actions, there is no point using them.

Personally I would advise against using the HTTP codes as your API error codes. After all you would want to distinguish between protocol errors and your API errors. Instead use 500 and put your error data in the body

3
  • I'd rather expect 409 (Conflict) when a resource cannot be created because it (i.e., a thing with the same unique key) already exists. Commented Jun 2 at 12:13
  • I think git uses that for something else. A good example of why reuse of http codes isnt the best solution though Commented Jun 2 at 13:35
  • To make things more interesting, RCF7807 (Problem Details) used 400 as an example of validation error details but the RFC9457 that replaces it now uses 422. ASP.NET Core returns 400 for validation errors though. The more generic Problem() response uses a configurable status code with 500 as a default Commented Jun 3 at 17:10

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.