400 BAD request HTTP error code meaning?

RestHttpError HandlingHttp Status-Code-400

Rest Problem Overview


I have a JSON request which I'm posting to a HTTP URL.

Should this be treated as 400 where requestedResource field exists but "Roman" is an invalid value for this field?

[{requestedResource:"Roman"}] 

Should this be treated as 400 where "blah" field doesn't exist at all?

[{blah:"Roman"}]

Rest Solutions


Solution 1 - Rest

A 400 means that the request was malformed. In other words, the data stream sent by the client to the server didn't follow the rules.

In the case of a REST API with a JSON payload, 400's are typically, and correctly I would say, used to indicate that the JSON is invalid in some way according to the API specification for the service.

By that logic, both the scenarios you provided should be 400s.

Imagine instead this were XML rather than JSON. In both cases, the XML would never pass schema validation--either because of an undefined element or an improper element value. That would be a bad request. Same deal here.

Solution 2 - Rest

From w3.org

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

Solution 3 - Rest

Selecting a HTTP response code is quite an easy task and can be described by simple rules. The only tricky part which is often forgotten is paragraph 6.5 from RFC 7231:

> Except when responding to a HEAD request, the server SHOULD send a > representation containing an explanation of the error situation, > and whether it is a temporary or permanent condition.

Rules are as following:

  1. If request was successful, then return 2xx code (3xx for redirect). If there was an internal logic error on a server, then return 5xx. If there is anything wrong in client request, then return 4xx code.
  2. Look through available response code from selected category. If one of them has a name which matches well to your situation, you can use it. Otherwise just fallback to x00 code (200, 400, 500). If you doubt, fallback to x00 code.
  3. Return error description in response body. For 4xx codes it must contain enough information for client developer to understand the reason and fix the client. For 5xx because of security reasons no details must be revealed.
  4. If client needs to distinguish different errors and have different reaction depending on it, define a machine readable and extendible error format and use it everywhere in your API. It is good practice to make that from very beginning.
  5. Keep in mind that client developer may do strange things and try to parse strings which you return as human readable description. And by changing the strings you will break such badly written clients. So always provide machine readable description and try to avoid reporting additional information in text.

So in your case I'd returned 400 error and something like this if "Roman" is obtained from user input and client must have specific reaction:

{
    "error_type" : "unsupported_resource",
    "error_description" : "\"Roman\" is not supported"
}

or a more generic error, if such situation is a bad logic error in a client and is not expected, unless developer made something wrong:

{
    "error_type" : "malformed_json",
    "error_description" : "\"Roman\" is not supported for \"requestedResource\" field"
}

Solution 4 - Rest

In neither case is the "syntax malformed". It's the semantics that are wrong. Hence, IMHO a 400 is inappropriate. Instead, it would be appropriate to return a 200 along with some kind of error object such as { "error": { "message": "Unknown request keyword" } } or whatever.

Consider the client processing path(s). An error in syntax (e.g. invalid JSON) is an error in the logic of the program, in other words a bug of some sort, and should be handled accordingly, in a way similar to a 403, say; in other words, something bad has gone wrong.

An error in a parameter value, on the other hand, is an error of semantics, perhaps due to say poorly validated user input. It is not an HTTP error (although I suppose it could be a 422). The processing path would be different.

For instance, in jQuery, I would prefer not to have to write a single error handler that deals with both things like 500 and some app-specific semantic error. Other frameworks, Ember for one, also treat HTTP errors like 400s and 500s identically as big fat failures, requiring the programmer to detect what's going on and branch depending on whether it's a "real" error or not.

Solution 5 - Rest

Using 400 status codes for any other purpose than indicating that the request is malformed is just plain wrong.

If the request payload contains a byte-sequence that could not be parsed as application/json (if the server expects that dataformat), the appropriate status code is 415:

> The server is refusing to service the request because the entity of > the request is in a format not supported by the requested resource for > the requested method.

If the request payload is syntactically correct but semantically incorrect, the non-standard 422 response code may be used, or the standard 403 status code:

> The server understood the request, but is refusing to fulfill it. > Authorization will not help and the request SHOULD NOT be repeated.

Solution 6 - Rest

Think about expectations.

As a client app, you expect to know if something goes wrong on the server side. If the server needs to throw an error when blah is missing or the requestedResource value is incorrect than a 400 error would be appropriate.

Solution 7 - Rest

First check the URL it might be wrong, if it is correct then check the request body which you are sending, the possible cause is request that you are sending is missing right syntax.

To elaborate , check for special characters in the request string. If it is (special char) being used this is the root cause of this error.

try copying the request and analyze each and every tags data.

Solution 8 - Rest

As a complementary, for those who might meet the same issue as mine, I'm using $.ajax to post form data to server and I also got the 400 error at first.

Assume I have a javascript variable,

var formData = {
    "name":"Gearon",
    "hobby":"Be different"
    }; 

Do not use variable formData directly as the value of key data like below:

$.ajax({
    type: "post",
    dataType: "json",
    url: "http://localhost/user/add",
    contentType: "application/json",
    data: formData,
    success: function(data, textStatus){
        alert("Data: " + data + "\nStatus: " + status); 
    }
});

Instead, use JSON.stringify to encapsulate the formData as below:

$.ajax({
    type: "post",
    dataType: "json",
    url: "http://localhost/user/add",
    contentType: "application/json",
    data: JSON.stringify(formData),
    success: function(data, textStatus){
        alert("Data: " + data + "\nStatus: " + status); 
    }
});

Anyway, as others have illustrated, the error is because the server could not recognize the request cause malformed syntax, I'm just raising a instance at practice. Hope it would be helpful to someone.

Solution 9 - Rest

This reminds me of a common dialog with others, "I understand - I just don't Agree"

400 means the server didn't understand

200 means the server understood exactly and fully processed the request.

When a server returns 200 it is saying, "I understood what you are asking for, I processed it without unexpected errors, and here is my proper response"

200 means you can trust the answer sent in the response. Maybe the answer is "Romans aren't allowed" - but still, it is a proper answer, generated without any unexpected problems.

200 doesn't express any information about Expected errors or Handled Exceptions - because that is not part of the Message Transport process. These are status codes about HTTP, the Status of the Transport itself.

I believe Blurring the line between "Transport/Communication" VS "Processing" should be avoided.

For those who prefer HTTP Codes to indicate problem in processing (the "I don't agree" part) it seems 409 Conflict is the most applicable to "Romans not allowed"
RFC 7231 409 Conflict

Conflict pretty much means "lack of agreement" right?

No matter what you choose for HTTP response code, it seems everyone agrees your response should explain Why it failed, and what to do to resolve it. In the case of Roman, maybe return a list of acceptable values for the field?

Solution 10 - Rest

In my case it meant that the data I was providing in json was not compatibile with required data for db, for example email address was already added into db and then it throws code 400

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPhoenixView Question on Stackoverflow
Solution 1 - RestVidyaView Answer on Stackoverflow
Solution 2 - RestJason SperskeView Answer on Stackoverflow
Solution 3 - RestAlexey GuseynovView Answer on Stackoverflow
Solution 4 - Restuser663031View Answer on Stackoverflow
Solution 5 - RestCochise RuhulessinView Answer on Stackoverflow
Solution 6 - Restfilm42View Answer on Stackoverflow
Solution 7 - RestAnkur BhutaniView Answer on Stackoverflow
Solution 8 - RestEugeneView Answer on Stackoverflow
Solution 9 - RestJo KempView Answer on Stackoverflow
Solution 10 - RestMariusz SidorowiczView Answer on Stackoverflow