HTTP 400 (bad request) for logical error, not malformed request syntax

131,018

Solution 1

As of this time, the latest draft of the HTTPbis specification, which is intended to replace and make RFC 2616 obsolete, states:

The 400 (Bad Request) status code indicates that the server cannot or will not process the request because the received syntax is invalid, nonsensical, or exceeds some limitation on what the server is willing to process.

This definition, while of course still subject to change, ratifies the widely used practice of responding to logical errors with a 400.

Solution 2

Status 422 (RFC 4918, Section 11.2) comes to mind:

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.

Solution 3

HTTPbis will address the phrasing of 400 Bad Request so that it covers logical errors as well. So 400 will incorporate 422.

From https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-p2-semantics-18#section-7.4.1
"The server cannot or will not process the request, due to a client error (e.g., malformed syntax)"

Solution 4

Even though, I have been using 400 to represent logical errors also, I have to say that returning 400 is wrong in this case because of the way the spec reads. Here is why i think so, the logical error could be that a relationship with another entity was failing or not satisfied and making changes to the other entity could cause the same exact to pass later. Like trying to (completely hypothetical) add an employee as a member of a department when that employee does not exist (logical error). Adding employee as member request could fail because employee does not exist. But the same exact request could pass after the employee has been added to the system.

Just my 2 cents ... We need lawyers & judges to interpret the language in the RFC these days :)

Thank You, Vish

Solution 5

It could be argued that having incorrect data in your request is a syntax error, even if your actual request at the HTTP level (request line, headers etc) is syntactically valid.

For example, if a Restful web service is documented as accepting POSTs with a custom XML Content Type of application/vnd.example.com.widget+xml, and you instead send some gibberish plain text or a binary file, it seems resasonable to treat that as a syntax error - your request body is not in the expected form.

I don't know of any official references to back this up though, as usual it seems to be down to interpreting RFC 2616.

Update: Note the revised wording in RFC 7231 §6.5.1:

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).

seems to support this argument more than the now obsoleted RFC 2616 §10.4.1 which said just:

The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.

Share:
131,018
Atif Aziz
Author by

Atif Aziz

Greetings, Netlings!

Updated on November 06, 2020

Comments

  • Atif Aziz
    Atif Aziz over 3 years

    The HTTP/1.1 specification (RFC 2616) has the following to say on the meaning of status code 400, Bad Request (§10.4.1):

    The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.

    There seems to be a general practice among a few HTTP-based APIs these days to use 400 to mean a logical rather than a syntax error with a request. My guess is that APIs are doing this to distinguish between 400 (client-induced) and 500 (server-induced). Is it acceptable or incorrect to use 400 to indicate non-syntactic errors? If it is acceptable, is there an annotated reference on RFC 2616 that provides more insight into the intended use of 400?

    Examples:

  • Atif Aziz
    Atif Aziz over 13 years
    That's certainly an interesting way to look at it. What about GET requests where an invalid query string parameter value is being used? Would you say 400 is fine to use because although the query string is well-formed, the query string parameter value has a syntax error per the application's view?
  • Day
    Day over 13 years
    RFC 4918 is the WebDAV RFC with which I'm not familiar. Is it ok to re-use the status code extensions to HTTP/1.1 in non-WebDAV HTTP services? The section on HTTP client compatibility would seem to indicate that it is. Does the IETF maintain a definitive list of all (core and extension) HTTP Codes to ensure that some other service that builds on HTTP doesn't introduce yet more codes that conflict with other extensions?
  • Julian Reschke
    Julian Reschke over 13 years
    Yes, it is ok. That's why there's a status code registry. See iana.org/assignments/http-status-codes.
  • Day
    Day over 13 years
    Well it seems a small step from the POST example that I gave, but I'll admit is seems a little icky to do the same with GET requests when the application finds parts of a URL to be invalid. In a truly Restful interface using HATEOAS (Hyptertext as the Engine of Application State), URLs for resources are not important for the client to know - clients merely follow links from other resources. But then most "REST" APIs don't stick to this principal and instead explain what query string parameters are required to be appended to what URL, so I guess in such services a 400 response would be ok.
  • Atif Aziz
    Atif Aziz over 13 years
    422 comes very close. The only shame is that it seems specifically concerned with an unprocessable entity as opposed to an unprocessable request. If only it encompassed the latter, it would also cover the case of HTTP GET because it comes with no entity. The description of 422, however, does make it clear that 400 is inappropriate for a logically invalid request.