338

What response code should be passed to client in case of following scenarios?

  1. Invalid data passed while user registration like wrong email format
  2. User name/ Email is already exists

I chose 403. I also found following that I feel can be used.

Wikipedia:

412 Precondition Failed : The server does not meet one of the preconditions that the requester put on the request

Suggest code if I should use other than 403.

Kowser
  • 8,123
  • 7
  • 40
  • 63
Amit Patel
  • 15,609
  • 18
  • 68
  • 106
  • Possible duplicate: http://stackoverflow.com/questions/3050518/what-http-status-response-code-should-i-use-if-the-request-is-missing-a-required – Genjo Aug 29 '16 at 10:34
  • I am resolving this issue also. Chapter 7.Validation of JAX-RS spec (2017) provides status code advice specifically for constraint violations. https://download.oracle.com/otn-pub/jcp/jaxrs-2_1-final-spec/jaxrs-2_1-final-spec.pdf?AuthParam=1546559699_8a1c42b298288ed02e280d293e710306 – burntsugar Jan 04 '19 at 01:21
  • `422` is the answer. The accepted answer below is wrong. HTTP status codes are a mess, but devs around the world have thought about this long and hard and selected `422`, not because it's great, but because it's the best we have. Avoid `403`, `409`, `412` etc. These have very specific technical meanings and should not be used for other things. `409` for example is for write/merge conflicts and should prompt the client to show some screen saying 'oops, someone else edited this record in the mean time` and give you a diff screen or something. – Stijn de Witt Aug 24 '22 at 08:06
  • This answer by Mike Deck should have been the accepted one: https://stackoverflow.com/a/9132152/286685 – Stijn de Witt Aug 24 '22 at 08:08

4 Answers4

366

400 is the best choice in both cases. If you want to further clarify the error you can either change the Reason Phrase or include a body to explain the error.

412 - Precondition failed is used for conditional requests when using last-modified date and ETags.

403 - Forbidden is used when the server wishes to prevent access to a resource.

The only other choice that is possible is 422 - Unprocessable entity.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • 11
    while it is often used in this context, 403 is not limited to acces control, since rfc2616-10.4.4 says: "The server understood the request, but is refusing to fulfill it. [...] if the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity." The reason can be invalid data. However, 422 is more applicable here. – Yannick Loiseau May 25 '11 at 14:19
  • 11
    Let's not get caught up in textual criticism. See for example http://trac.tools.ietf.org/wg/httpbis/trac/ticket/294 which attempts to clarify that 403 is and was always about authorization. – fumanchu May 25 '11 at 14:44
  • 1
    @fumanchu It means 403 should be return in case of user don't have permission to access requested resource. But I think 401 Unauthorized is more appropriate of accessing resource on which user doesn't have permission. – Amit Patel May 26 '11 at 04:45
  • @fumanchu It is also stated that "Authorization will not help and the request SHOULD NOT be repeated." for 403. What I understand here is is even you have special privileges/permission, you cannot access resource. – Amit Patel May 26 '11 at 04:58
  • @Amit The link that @funmanchu pointed to is a recommendation to remove the line you quoted because of the confusion that it is causing. – Darrel Miller May 26 '11 at 11:04
  • My comment was mostly in response to Yannick. Sorry for not making that clear. – fumanchu May 26 '11 at 15:30
  • 1
    401 Unauthorized will prompt a web browser to show the user the standard HTTP username/password prompt. If you're not using that kind of authentication for your service, or if the user already has HTTP authentication, 401 is not appropriate. – Greg Ball May 09 '12 at 03:41
  • @DarrelMiller Please do you think you could help me with this question http://goo.gl/qiOdmT – Axel Nov 10 '14 at 03:36
  • ode to report client bug – Mawg says reinstate Monica Dec 07 '15 at 10:07
  • [this](https://www.bennadel.com/blog/2434-http-status-codes-for-invalid-data-400-vs-422.htm) explains 400 vs 422 well. – Amber Kulkarni Feb 27 '18 at 05:28
  • @GregBall The browser will not normally do anything with the response from an Ajax call. That's left up to the script making the call. So actually, 401 is just fine for REST apis. You are right when it comes to web pages. But for REST apis it's perfectly fine. – Stijn de Witt Oct 22 '18 at 11:02
  • On the first scenario I will choose 400, because the user could know the right format before create his "bad request". On the second scenario I prefer to use 422, because the request format is correct but some internal validation refuses his request. – Dherik Jan 15 '20 at 12:23
  • What about when client wants to delete a picture and passes correct data (id of the picture) but the client is not owner of this picture (according to records in database) so the deletion of the picture will fail? 400 with additional explanation? – Eru Mar 21 '22 at 20:24
  • 1
    This answer is wrong. 400 means that the server did not understand the request. In both cases above, the server understood the request, but is refusing to fulfill it (the definition of HTTP 403). The second case could also arguably be handled with a 409 (conflict). – Greg Brown Aug 21 '22 at 12:21
  • @StijndeWitt A 401 response means that the caller either did not provide credentials or provided invalid credentials. Despite its name, it is not actually meant to represent an "unauthorized" response. "Unauthenticated" would have been a better name for this status. – Greg Brown Aug 21 '22 at 12:24
  • 1
    @GregBrown Yes you are 100% right. 'Unauthorized' is downright wrong for this status code. It's very unfortunate this happened because it makes stuff very unclear for new devs. Maybe even better as the name for this status code would be something like `not logged in` or `login required`, because obviously people have trouble distinguisihing between 'Unauthorized' and 'Unauthenticated'. Also, everyone shortens it to 'Auth', which makes it even more unclear. – Stijn de Witt Aug 24 '22 at 07:27
  • 1
    I agree with @GregBrown that `400 Bad Request` is simply wrong for the scenario where e.g. an email address has the wrong format. The meaning of `400` is very simple, that the server was unable to read (parse) the request. In the case of malformed JSON, 400 is perfect. But as soon as the request can be parsed successfully, `400` becomes the wrong status code. `422` has become the de facto standard response for validation errors and is the most suitable for the scenarios mentioned by the OP. – Stijn de Witt Aug 24 '22 at 07:31
  • *"400 is the best choice in both cases."* Had to downvote for this. `422` is the only code you mention that makes sense. `400 Bad Request` is for when the request was malformed, not for when the content was invalid in terms of business rules. – Stijn de Witt Aug 24 '22 at 07:33
  • 1
    @Eru *"What about when client wants to delete a picture and passes correct data (id of the picture) but the client is not owner of this picture"* `403 Forbidden` would be the only sensible choice in this scenario. This is one of the best standardized status codes. Basically, if the client is not (yet) logged in, you would return `401`. If he is logged in but lacks permissions (as in your example), `403` is the answer. – Stijn de Witt Aug 24 '22 at 08:11
121

I would recommend 422. It's not part of the main HTTP spec, but it is defined by a public standard (WebDAV) and it should be treated by browsers the same as any other 4xx status code.

From RFC 4918:

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.

Community
  • 1
  • 1
Mike Deck
  • 18,045
  • 16
  • 68
  • 92
  • 25
    Note that the quoted text states that 422 is applicable when the request entity is syntactically well-formed, but semantically erroneous. If the request entity is garbled, 400 is the appropriate response. – Matty K Aug 20 '12 at 01:59
  • This seems to have become a de-facto standard. Many API's have opted for `422` in this scenario and it has gotten independent of WebDAV. – Stijn de Witt Aug 24 '22 at 07:22
  • @MattyK is 100% correct. This is THE distinction to make, and is why the accepted answer is wrong. `400 Bad Request` is for when the server is unable to parse the request. And though 422 was initially defined for WebDAV, it's simply the most suitable response code in the 4xx range and has been selected by so many APIs and frameworks now for validation errors that is has become the standard. – Stijn de Witt Aug 24 '22 at 07:43
107

If the request could not be correctly parsed (including the request entity/body) the appropriate response is 400 Bad Request [1].

RFC 4918 states that 422 Unprocessable Entity is applicable when the request entity is syntactically well-formed, but semantically erroneous. So if the request entity is garbled (like a bad email format) use 400; but if it just doesn't make sense (like @example.com) use 422.

If the issue is that, as stated in the question, user name/email already exists, you could use 409 Conflict [2] with a description of the conflict, and a hint about how to fix it (in this case, "pick a different user name/email"). However in the spec as written, 403 Forbidden [3] can also be used in this case, arguments about HTTP Authorization notwithstanding.

412 Precondition Failed [4] is used when a precondition request header (e.g. If-Match) that was supplied by the client evaluates to false. That is, the client requested something and supplied preconditions, knowing full well that those preconditions might fail. 412 should never be sprung on the client out of the blue, and shouldn't be related to the request entity per se.

Community
  • 1
  • 1
Matty K
  • 3,781
  • 2
  • 22
  • 19
  • 1
    I should note the updated HTTP/1.1 RFCs: 400 Bad Request, 409 Conflict, 403 Forbidden etc. live in http://tools.ietf.org/html/rfc7231 ; 412 Precondition Failed is in http://tools.ietf.org/html/rfc7232#section-4.2 – Matty K Jul 03 '14 at 03:49
  • *"If the issue is that, as stated in the question, user name/email already exists, you could use 409 Conflict [2] "*. No, that's not what `409 Conflict` is about. It's very specifically about write conflicts. So if your database transaction fails because the record you tried to write was modified by another user in between you reading and changing the record and you writing it, that's exactly what `409` is for. Think optimistic locking etc. It's not for validation errors. `422` is the best choice in both of the scenarios described by the OP. – Stijn de Witt Aug 24 '22 at 07:47
  • 1
    *"if the request entity is garbled (like a bad email format) use 400;"* Unless the message body was expected to be an email address, I disagree. For scenarios where the message body is expected to be e.g. JSON or XML, `400 Bad Request` is only for when that JSON or XML is malformed, not for when any of the data embedded in it is wrong. Basically, when you write a server, you do something like`try {const json = JSON.parse(request.body); if (! isValid(json)) { response.status = 422 } else { response.status = 200 } } catch (e) { response.status = 400}` – Stijn de Witt Aug 24 '22 at 07:52
54

It is amusing to return 418 I'm a teapot to requests that are obviously crafted or malicious and "can't happen", such as failing CSRF check or missing request properties.

2.3.2 418 I'm a teapot

Any attempt to brew coffee with a teapot should result in the error code "418 I'm a teapot". The resulting entity body MAY be short and stout.

To keep it reasonably serious, I restrict usage of funny error codes to RESTful endpoints that are not directly exposed to the user.

Community
  • 1
  • 1
doug65536
  • 6,562
  • 3
  • 43
  • 53
  • 14
    Implement it such that your API returns `418 I'm a teapot` for all requests coming from your boss :) – vikarjramun Apr 10 '17 at 23:33
  • 2
    @vikarjramun i´ve builded a dummy REST and made pruductive one offline. (prerelease) now our students are searching trying to create valid data-requests but it´s all teapot. I´m the "boss" - but it´s working too. – LenglBoy Dec 20 '17 at 16:06
  • 2
    This RFC is dumb. You can make coffee in a tea pot, so long as you pour it through a tea strainer into your cup. Just like using loose leaf tea. You can also make tea in a cafetiere with no issues. – speciesUnknown Jun 21 '19 at 15:54
  • 2
    @gburton That does require intervention by a human, though. Over the network, you definitely need a coffee-capable device to make coffee. Of course, a coffee-and-teapot should not respond with a 418. – Jasper Jul 22 '19 at 11:42
  • 2
    This status code would have been funny if the rest of the HTTP status code was an orderly and clean spec. But it's not, it's a mess, as this question and it's many wrong answers attests to. So humour is great, but not when you are joking around while the real work is a mess. HTTP status codes are 80% focussed inwards. They are about HTTP. When in reality, we need status codes at the application level. The fact that the world is using `422 Unprocessable Entity` borrowed from WebDAV for a basic thing as validation errors is telling. The HTTP people just forgot... Too busy joking about teapots... – Stijn de Witt Aug 24 '22 at 07:56