400 vs 422 response to POST of data
Asked Answered
A

9

549

I'm trying to figure out what the correct status code to return on different scenarios with a "REST-like" API that I'm working on. Let's say I have an end point that allows POST'ing purchases in JSON format. It looks like this:

{
    "account_number": 45645511,
    "upc": "00490000486",
    "price": 1.00,
    "tax": 0.08
}

What should I return if the client sends me "sales_tax" (instead of the expected "tax"). Currently, I'm returning a 400. But, I've started questioning myself on this. Should I really be returning a 422? I mean, it's JSON (which is supported) and it's valid JSON, it's just doesn't contain all of the required fields.

Ascomycete answered 21/4, 2013 at 17:13 Comment(1)
possible duplicate of REST: Mapping application errors to HTTP Status codesNitrous
E
592

400 Bad Request would now seem to be the best HTTP/1.1 status code for your use case.

At the time of your question (and my original answer), RFC 7231 was not a thing; at which point I objected to 400 Bad Request because RFC 2616 said (with emphasis mine):

The request could not be understood by the server due to malformed syntax.

and the request you describe is syntactically valid JSON encased in syntactically valid HTTP, and thus the server has no issues with the syntax of the request.

However as pointed out by Lee Saferite in the comments, RFC 7231, which obsoletes RFC 2616, does not include that restriction:

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


However, prior to that re-wording (or if you want to quibble about RFC 7231 only being a proposed standard right now), 422 Unprocessable Entity does not seem an incorrect HTTP status code for your use case, because as the introduction to RFC 4918 says:

While the status codes provided by HTTP/1.1 are sufficient to describe most error conditions encountered by WebDAV methods, there are some errors that do not fall neatly into the existing categories. This specification defines extra status codes developed for WebDAV methods (Section 11)

And the description of 422 says:

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.

(Note the reference to syntax; I suspect 7231 partly obsoletes 4918 too)

This sounds exactly like your situation, but just in case there was any doubt, it goes on to say:

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

(Replace "XML" with "JSON" and I think we can agree that's your situation)

Now, some will object that RFC 4918 is about "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)" and that you (presumably) are doing nothing involving WebDAV so shouldn't use things from it.

Given the choice between using an error code in the original standard that explicitly doesn't cover the situation, and one from an extension that describes the situation exactly, I would choose the latter.

Furthermore, RFC 4918 Section 21.4 refers to the IANA Hypertext Transfer Protocol (HTTP) Status Code Registry, where 422 can be found.

I propose that it is totally reasonable for an HTTP client or server to use any status code from that registry, so long as they do so correctly.


But as of HTTP/1.1, RFC 7231 has traction, so just use 400 Bad Request!

Elnoraelnore answered 26/11, 2013 at 11:26 Comment(24)
Pin.net uses 422 for validation like errors if you send the wrong or missing data even with valid JSON structure. But it also sends 400 if the processing of the credit card number failed, that is there wasn't enough money in the card, or there's a suspected fraud... etc. It's a bit weird, but the descriptions of 400 or 422 don't fit the credit card situation. Or maybe they all fall under "validation errors".Womanhood
you should use 422 only if you support WebDAV methods.Vasily
Your answer (422) makes sense to me. This is also what Rails (respond_with) uses when a resource couldn't be processed because of validation errors.Statis
I also agree with that answer, and I reached the same conclusion while browsing the different HTTP error codes. Is there some sort of consensus on this issue in the REST community though ?Ranchero
422 is known and tracked code: iana.org/assignments/http-status-codes/http-status-codes.xhtml Subsequent standards will have in mind this code and it is possible in future have 422 in HTTP codes RFC with same semantic. Use it when you have needs.Molybdic
Note the use of 422 in non-WebDAV spec here: tools.ietf.org/html/rfc5789#section-2.2Truncheon
Just as an update, RFC 7231 has a different description for response code 400 that changes the semantics.Candelaria
Only thing I don't (didn't) understand is what changed in RFC 7231 that makes you think it's the correct answer now. I actually just re-read it though and now I get it. This could be worded slightly better by putting the answer first and the older answer history after, but thanks for the info!Insipid
i don't understand this answer probably because i'm weak in English or because i don't know what WebDav exactly is. can somebody please tell me is it safe to use 422? @KristianGlass says in the answer: i would chose the latter. and by latter he meas 422. and at the bottom of the answer he says just use 400. so which should i use in this kind of situation? 422 seems better. but the last line of this post, i don't get it.Magnolia
My apologies - I updated this answer to reflect the change in RFCs and lost some clarity; I'll try to refactor. It is almost certainly safe to use 422, but nowadays you should use 400.Elnoraelnore
Am I correct in inferring that the answer to the more general question "when to use 400 and when 422?" is: "use 400 when the request is syntactically is malformed, use 422 when the request is semantically malformed"?Vaillancourt
@Vaillancourt Prior to RFC 7231 I would have nodded enthusiastically; now it feels like 400 is probably most appropriate for bothElnoraelnore
@KristianGlass So are there then any situations left in which 422 should be used over 400?Vaillancourt
Inanc - I rolled back your edit because the double negative was very deliberate - I explicitly would not claim correctness, just lack of clear incorrectnessElnoraelnore
I still think the spec could be a lot clearer. The examples given in the are clear cases of the client doing something wrong. The OP's situation also falls into that category. However, there are cases like "I understand what you're asking, but I refuse to do it because there is some business rule against it" is not so clear cut. It's not exactly the client's fault, so a 403 might actually apply, per the same spec: "However, a request might be forbidden for reasons unrelated to the credentials". I'd prefer to have separate codes for permission related stuff vs "it cannot be done" though.Irritating
I think it's stupid that the standards were change to fit the current status code usage patterns. It's like changing REST principles by dropping PUT and DELETE and replacing them with POST, because people often use POST for Update/Delete operations. Bad request now tells you either YOU made request with wrong syntax or the SERVER decided to refuse your request for some reason. It is such a mix of concerns I don't even believe it!Limoges
As far as I understand, in case of the missing required attributes the solution suggested here is to use 400 status code. But jersey bean validator in java returns 422 in this case which is widely accepted standard library. Please suggest.Farro
Just let me get this straight, is RFC 7231 the latest? If so, there is no mention of 422 in there so does that mean it's now obsolete?Dashpot
No wonder everyone is confused. I am still confused. ;-)Backward
So if a phone number is sent with some alphabets like a123fs2 instead of all numbers and the creation of that object in the DB fails - is this an example for 422 error? If not can you give an example ...Aspinwall
most confusing answer. not sure of these many upvotesPhosphorus
I think rfc9110 might have something to say about it now. It seems that it is now not just WebDAV specific anymore, but I might be misreading it.Deluge
RFC 7231 broadens the applicability of 400, but all of the examples given are places where the server doesn't believe it can accurately parse the request at all based on a fundamental problem at the HTTP protocol level. None of them require knowledge of the server's business logic. To me this glaring omission strongly implies that IETF does not intend business logic rejections to be part of 400. I disagree with the update to this answer and think it was stronger in the previous version which recommended 422 (the logic for which is still applicable).Machiavellian
RFC 7231 has been superseded by RFC 9110, which includes 422. Based on plain reading of the 400 and 422 descriptions, you could reasonably interpret either as being appropriate for a misnamed property.Ludewig
D
203

Case study: GitHub API

The following quote is from: https://github.com/github/docs/blob/a287621b0663ef940e6d026650f450d300805fab/content/rest/overview/resources-in-the-rest-api.md#client-errors It used to be visible at: https://docs.github.com/en/rest/overview/resources-in-the-rest-api#client-errors but that was removed and has no archives of the time as of 2024.

Maybe copying from well known APIs is a wise idea:

There are three possible types of client errors on API calls that receive request bodies:

Sending invalid JSON will result in a 400 Bad Request response:

HTTP/1.1 400 Bad Request
Content-Length: 35
{"message":"Problems parsing JSON"}

Sending the wrong type of JSON values will result in a 400 Bad Request response:

HTTP/1.1 400 Bad Request
Content-Length: 40

{"message":"Body should be a JSON object"}

Sending invalid fields will result in a 422 Unprocessable Entity response:

HTTP/1.1 422 Unprocessable Entity
Content-Length: 149

{
  "message": "Validation Failed",
  "errors": [
    {
      "resource": "Issue",
      "field": "title",
      "code": "missing_field"
    }
  ]
}
Dyspnea answered 17/9, 2018 at 8:46 Comment(8)
Can't upvote it more. Wish that more upvoted answers would refer to this one. The specs (RFC, IANA) epically failed to provide clear definitions and distinction between the two. So the answer boils down to best practices and GitHub gives us one.Menu
So 422 is correct if e.g. "price" or "tax" hadn't been valid numbers? Basically violating the schema expected. Or if you tried to bill someone not in your system and you only bill people that are registered customers?Brink
I don't think this answer is clear. Missing field can be a field that has not been sent and that's clearly a 400 to me, because the app cannot understand this payload, it violates the contract. IMHO, 400 suits better to not well-formed JSON, JSON that has different key names (contract violation) and JSON that one or more of the field(s) contents is from another type, let's say, you expect a int and got an object. Even not null constraint can be in both status codes, 400 if field not sent at all (and most frameworks understands it as null), and 422 if sent but with null value.Youthen
@PhilippeGioseffi To me, invalid JSON with a JSON content type comes across as "I can't even parse this request" and fits 400 well. (Random data with a non-JSON content type probably gets a 415.) Valid JSON missing a required field comes across as "I see that you've tried to post a new xyz, but it is not valid," and fits 422 well. I've no particular beef with people who use them differently (and I don't think the exact point where you draw that line even matters much), but this distinction feels decently clear and intuitive to me.Machiavellian
If the JSON is malformed ie invalid required fields then 400. If the JSON is missing optional fields that might be needed to process the request, then 422. If the JSON contains valid fields, but the values of the fields are preventing the request from being processed (eg. insufficient funds) then 422. The key difference between 400 and 422 to me is 422 the server understands the request, but it cannot complete the request due to the values themselves (not the type of values). 400 is when the server wont attempt to process the request, as the JSON is incorrect - invalid fields / value types.Aphorism
According with developer.mozilla.org/en-US/docs/Web/HTTP/Status/422: > and the syntax of the request entity is correct, but it was unable to process the contained instructions. That means the payload is well-formed, and the server understands the request. But for other reasons, it cannot proceed. So I agree with @leo_cape. This answer is not correct.Pink
That's just Rails. :xDKnapweed
The linked github page does not seem to describe client errors any more.Dryfoos
C
46

400 Bad Request is proper HTTP status code for your use case. The code is defined by HTTP/0.9-1.1 RFC.

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

https://www.rfc-editor.org/rfc/rfc2616#section-10.4.1

422 Unprocessable Entity is defined by RFC 4918 - WebDav. Note that there is slight difference in comparison to 400, see quoted text below.

This error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.

To keep uniform interface you should use 422 only in a case of XML responses and you should also support all status codes defined by Webdav extension, not just 422.

https://www.rfc-editor.org/rfc/rfc4918#page-78

See also Mark Nottingham's post on status codes:

it’s a mistake to try to map each part of your application “deeply” into HTTP status codes; in most cases the level of granularity you want to be aiming for is much coarser. When in doubt, it’s OK to use the generic status codes 200 OK, 400 Bad Request and 500 Internal Service Error when there isn’t a better fit.

How to Think About HTTP Status Codes

Choriamb answered 23/4, 2013 at 14:32 Comment(4)
422 code is part of IANA registry iana.org/assignments/http-status-codes/http-status-codes.xhtml so any IMHO have no sense. In any case Facebook and Twitter REST API reinvent own codes and don't use RFC/IANA standards. So you can do.Molybdic
Section 11 specifically states they are added to the entire spec and not just within the WebDav spec: The following status codes are added to those defined in HTTP/1.1 [RFC2616].Jealousy
Just because the code is described as part of the WebDAV spec doesn't mean it's WebDAV-specific! Status codes are supposed to be generic.Unshackle
Leaving aside the debate about the exact meaning of 422, I think the quote from Mark Nottingham is excellent advice. And also this one, from the linked article: 'Trying to make your application “fit” into a set of status codes is only going to cause pain and disappointment. Don’t do it.'Quotable
F
42

To reflect the status as of 2015:

Behaviorally both 400 and 422 response codes will be treated the same by clients and intermediaries, so it actually doesn't make a concrete difference which you use.

However I would expect to see 400 currently used more widely, and furthermore the clarifications that the HTTPbis spec provides make it the more appropriate of the two status codes:

  • The HTTPbis spec clarifies the intent of 400 to not be solely for syntax errors. The broader phrase "indicates that the server cannot or will not process the request due to something which is perceived to be a client error" is now used.
  • 422 is specifically a WebDAV extension, and is not referenced in RFC 2616 or in the newer HTTPbis specification.

For context, HTTPbis is a revision of the HTTP/1.1 spec that attempts to clarify areas that were unclear or inconsistent. Once it has reached approved status it will supersede RFC2616.

Flannery answered 13/1, 2015 at 10:16 Comment(3)
Doesn't the 403 Forbidden might also be used for this context then? Quote: The 403 (Forbidden) status code indicates that the server understood the request but refuses to authorize it...If authentication credentials were provided in the request, the server considers them insufficient to grant access....However, a request might be forbidden for reasons unrelated to the credentials. So it looks like 403 can be used to reject requests outside of authentication.Procumbent
@Procumbent note that "rejected for reasons outside of credentials" != "rejected for reasons outside of authentication." There are lots of ways to authenticate someone without using credentials, specifically.Marivaux
@Procumbent no, credentials means authentication ("who are you"), which would be 401 upon failure. Authorisation ("what can you do") would be 403 upon failure. Full explanation here: https://mcmap.net/q/40375/-403-forbidden-vs-401-unauthorized-http-responses Neither apply to the OP's "missing fields" situation because the error would be the same regardless of which user attempted it. I agree 400 is the right answer.Beg
E
23

There is no correct answer, since it depends on what the definition of "syntax" is for your request. The most important thing is that you:

  1. Use the response code(s) consistently
  2. Include as much additional information in the response body as you can to help the developer(s) using your API figure out what's going on.=

Before everyone jumps all over me for saying that there is no right or wrong answer here, let me explain a bit about how I came to the conclusion.

In this specific example, the OP's question is about a JSON request that contains a different key than expected. Now, the key name received is very similar, from a natural language standpoint, to the expected key, but it is, strictly, different, and hence not (usually) recognized by a machine as being equivalent.

As I said above, the deciding factor is what is meant by syntax. If the request was sent with a Content Type of application/json, then yes, the request is syntactically valid because it's valid JSON syntax, but not semantically valid, since it doesn't match what's expected. (assuming a strict definition of what makes the request in question semantically valid or not).

If, on the other hand, the request was sent with a more specific custom Content Type like application/vnd.mycorp.mydatatype+json that, perhaps, specifies exactly what fields are expected, then I would say that the request could easily be syntactically invalid, hence the 400 response.

In the case in question, since the key was wrong, not the value, there was a syntax error if there was a specification for what valid keys are. If there was no specification for valid keys, or the error was with a value, then it would be a semantic error.

Endoblast answered 31/1, 2014 at 19:17 Comment(3)
Very underrated answer - thanks for the well worded explanation.Jape
Exactly my thoughts on the matter! I'm coming from XML SOAP background and concept of schema just got into my blood and JSON documents rather don't announce their schema. To me it's whether server "understands" the request or not. If server doesn't know what "sales_tax" is then it's simply 400: "I have no idea what you sent me but definitely not what I want.".Jahnke
Thank you, now understood which one I should use.Rexrexana
A
4

Your case: HTTP 400 is the right status code for your case from REST perspective as its syntactically incorrect to send sales_tax instead of tax, though its a valid JSON. This is normally enforced by most of the server side frameworks when mapping the JSON to objects. However, there are some REST implementations that ignore new key in JSON object. In that case, a custom content-type specification to accept only valid fields can be enforced by server-side.

Ideal Scenario for 422:

In an ideal world, 422 is preferred and generally acceptable to send as response if the server understands the content type of the request entity and the syntax of the request entity is correct but was unable to process the data because its semantically erroneous.

Situations of 400 over 422:

Remember, the response code 422 is an extended HTTP (WebDAV) status code. There are still some HTTP clients / front-end libraries that aren't prepared to handle 422. For them, its as simple as "HTTP 422 is wrong, because it's not HTTP". From the service perspective, 400 isn't quite specific.

In enterprise architecture, the services are deployed mostly on service layers like SOA, IDM, etc. They typically serve multiple clients ranging from a very old native client to a latest HTTP clients. If one of the clients doesn't handle HTTP 422, the options are that asking the client to upgrade or change your response code to HTTP 400 for everyone. In my experience, this is very rare these days but still a possibility. So, a careful study of your architecture is always required before deciding on the HTTP response codes.

To handle situation like these, the service layers normally use versioning or setup configuration flag for strict HTTP conformance clients to send 400, and send 422 for the rest of them. That way they provide backwards compatibility support for existing consumers but at the same time provide the ability for the new clients to consume HTTP 422.


The latest update to RFC7321 says:

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 confirms that servers can send HTTP 400 for invalid request. 400 doesn't refer only to syntax error anymore, however, 422 is still a genuine response provided the clients can handle it.

Anima answered 22/2, 2017 at 18:21 Comment(0)
S
4

422 Unprocessable Entity Explained Updated: March 6, 2017

What Is 422 Unprocessable Entity?

A 422 status code occurs when a request is well-formed, however, due to semantic errors it is unable to be processed. This HTTP status was introduced in RFC 4918 and is more specifically geared toward HTTP extensions for Web Distributed Authoring and Versioning (WebDAV).

There is some controversy out there on whether or not developers should return a 400 vs 422 error to clients (more on the differences between both statuses below). However, in most cases, it is agreed upon that the 422 status should only be returned if you support WebDAV capabilities.

A word-for-word definition of the 422 status code taken from section 11.2 in RFC 4918 can be read below.

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.

The definition goes on to say:

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

400 vs 422 Status Codes

Bad request errors make use of the 400 status code and should be returned to the client if the request syntax is malformed, contains invalid request message framing, or has deceptive request routing. This status code may seem pretty similar to the 422 unprocessable entity status, however, one small piece of information that distinguishes them is the fact that the syntax of a request entity for a 422 error is correct whereas the syntax of a request that generates a 400 error is incorrect.

The use of the 422 status should be reserved only for very particular use-cases. In most other cases where a client error has occurred due to malformed syntax, the 400 Bad Request status should be used.

https://www.keycdn.com/support/422-unprocessable-entity/

Suture answered 13/7, 2017 at 5:6 Comment(0)
O
3

400 - Failed the request validation like if the data is missing, if it has a wrong type, etc. so it is given a status of 400.

422 - Passes the request validation, but failed the operation process, because the the request data, or part of it is giving an error to the to the operation, but is handled, and given a status of 422.

Outgrow answered 18/1, 2023 at 22:46 Comment(0)
F
-3

Firstly this is a very good question.

400 Bad Request - When a critical piece of information is missing from the request

e.g. The authorization header or content type header. Which is absolutely required by the server to understand the request. This can differ from server to server.

422 Unprocessable Entity - When the request body can't be parsed.

This is less severe than 400. The request has reached the server. The server has acknowledged the request has got the basic structure right. But the information in the request body can't be parsed or understood.

e.g. Content-Type: application/xml when request body is JSON.

Here's an article listing status codes and its use in REST APIs. https://metamug.com/article/status-codes-for-rest-api.php

Fuchs answered 9/11, 2017 at 14:20 Comment(4)
422 means that the syntax is valid, but the contents are not. Sending JSON where XML is expected means that the syntax is wrong, so a 400 is the correct response in this case.Identical
Exactly as Dirk said 422 means syntactically valid request (can be parsed and understood) but semantically invalidAugustusaugy
400: when the request can't be processed because of invalid syntax (e.g. parsing error); 422: when the request can't be processed because of invalid data (e.g. validation error).Spikenard
Your example for 422 is not valid because by sending json with an application/xml media type, the body automatically is syntactically incorrect and the response should be 400.Raze

© 2022 - 2024 — McMap. All rights reserved.