What's an appropriate HTTP status code to return by a REST API service for a validation failure?
Asked Answered
B

9

459

I'm currently returning 401 Unauthorized whenever I encounter a validation failure in my Django/Piston based REST API application. Having had a look at the HTTP Status Code Registry I'm not convinced that this is an appropriate code for a validation failure, what do y'all recommend?

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 405 Method Not Allowed
  • 406 Not Acceptable
  • 412 Precondition Failed
  • 417 Expectation Failed
  • 422 Unprocessable Entity
  • 424 Failed Dependency

Update: "Validation failure" above means an application level data validation failure, i.e., incorrectly specified datetime, bogus email address etc.

Batty answered 24/12, 2009 at 22:34 Comment(3)
Check out this answer: https://mcmap.net/q/55679/-proper-use-of-http-status-codes-in-a-quot-validation-quot-serverEnvelop
Fwiw, Kenny's link suggests code 422, as Jim's answer now does below. #TheMoreYouKnow #SavingYouAClickIncommutable
I think 401 is more clear.Scan
D
340

If "validation failure" means that there is some client error in the request, then use HTTP 400 (Bad Request). For instance if the URI is supposed to have an ISO-8601 date and you find that it's in the wrong format or refers to February 31st, then you would return an HTTP 400. Ditto if you expect well-formed XML in an entity body and it fails to parse.

(1/2016): Over the last five years WebDAV's more specific HTTP 422 (Unprocessable Entity) has become a very reasonable alternative to HTTP 400. See for instance its use in JSON API. But do note that HTTP 422 has not made it into HTTP 1.1, RFC-7231.

Richardson and Ruby's RESTful Web Services contains a very helpful appendix on when to use the various HTTP response codes. They say:

400 (“Bad Request”)
Importance: High.
This is the generic client-side error status, used when no other 4xx error code is appropriate. It’s commonly used when the client submits a representation along with a PUT or POST request, and the representation is in the right format, but it doesn’t make any sense. (p. 381)

and:

401 (“Unauthorized”)
Importance: High.
The client tried to operate on a protected resource without providing the proper authentication credentials. It may have provided the wrong credentials, or none at all. The credentials may be a username and password, an API key, or an authentication token—whatever the service in question is expecting. It’s common for a client to make a request for a URI and accept a 401 just so it knows what kind of credentials to send and in what format. [...]

Denotative answered 25/12, 2009 at 4:13 Comment(13)
But probably if the URI format is invalid an 404 might more appropriate.Great
As stated by @ReWrite, I also think 422 is better for validation errors.Indicant
I'd say this is wrong. 400 Bad Request is used when there is syntactically something wrong with the request. I'd say ReWrite is right in recommending 422 which is about the content of the request.Hickok
@Kenji yes, 401 (“Unauthorized”): "It may have provided the wrong credentials..." means wrong user and/or password.Nannettenanni
@Jim if username & password are valid string but however either the user doesn't exist or password is incorrect, in such scenario I should return 400 or 401 ?? Because Owin returns 400 in this scenarioTonisha
According to the spec, it should be a 422 error, not a 400/401Cramoisy
@ZacharyWeixelbaum According to the WebDAV spec you should use a 422 instead of a 400, so as long as the WebDAV vs HTTP distinction doesn't matter to you then for sure go ahead and use 422. But you should never return a 422 in place of a 401. Returning a 422 instead of a 401 is always wrongDenotative
@JimFerrans 400 errors are for where the syntax given is incorrect. 401 errors are specifically if I am trying to access a page that I need to be logged in to access and I am not logged in at all. 422 errors are for where the syntax is correct, but the server is refusing service. Wrong username/password is correct syntax (not 400 error) and I am not trying to access a page that I need to be logged in for because I am accessing the login page itself (not 401 error). The 401 error should be used for something like a settings page that only a user can accessCramoisy
@ZacharyWeixelbaum - if you're talking specifically about the log-in page only, then you don't need a 4xx code at all because the operation was successful. You went to the log-in page, entered incorrect credentials and received the appropriate error message. You saw the page you asked for: HTTP 200.Creative
@EdGraham 200 is only for when everything is successful. When you login with incorrect credentials, or when you try accessing a page without proper authentication, then that is an error and you need to show some sort of code to let the user know that there was an errorCramoisy
@ZacharyWeixelbaum - I respectfully disagree. A search that returns no results may or may not be successful; but it should still return an HTTP 200 as it's a valid use-case for the search facility. Similarly, I would say that logging in with incorrect credentials is a valid use-case; users with good intentions will occasionally do this. They won't try to reach secure pages without logging in, however, so that merits a 401. In ASP.NET (for example), a non-200 return code causes an exception to be thrown and therefore dealt with. This isn't desirable for frequent events.Creative
@EdGraham it depends upon whether you look at the role of a login POST as to either (1) attempt to log you in (in which case invalid credentials does not inhibit the attempt itself), or instead (2) actually log you in, in which case invalid credentials does indeed inhibit you. You look at it as #1, and some people look at it as #2.Serapis
@Serapis - you are absolutely right. And in the intervening three and a half years, I think I have come around to Zachary's way of thinking!Creative
S
111

From RFC 4918 (and also documented at http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml):

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.

Somnambulation answered 25/8, 2014 at 15:43 Comment(1)
I would recommend 422 - Unprocessable Entity for validation failures over 400 - Bad RequestTopflight
F
37

A duplicate in the database should be a 409 CONFLICT.

I recommend using 422 UNPROCESSABLE ENTITY for validation errors.

I give a longer explanation of 4xx codes here: http://parker0phil.com/2014/10/16/REST_http_4xx_status_codes_syntax_and_sematics/

Fulcrum answered 16/10, 2014 at 23:6 Comment(0)
A
26

Here it is:

rfc2616#section-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.

rfc7231#section-6.5.1 - 6.5.1. 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).

Refers to malformed (not wellformed) cases!

rfc4918 - 11.2. 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.

Conclusion

Rule of thumb: [_]00 covers the most general case and cases that are not covered by designated code.

422 fits best object validation error (precisely my recommendation:)
As for semantically erroneous - Think of something like "This username already exists" validation.

400 is incorrectly used for object validation

Agripinaagrippa answered 4/12, 2015 at 12:53 Comment(0)
S
9

I would say technically it might not be an HTTP failure, since the resource was (presumably) validly specified, the user was authenticated, and there was no operational failure (however even the spec does include some reserved codes like 402 Payment Required which aren't strictly speaking HTTP-related either, though it might be advisable to have that at the protocol level so that any device can recognize the condition).

If that's actually the case, I would add a status field to the response with application errors, like

<status><code>4</code><message>Date range is invalid</message></status>

Sardius answered 24/12, 2009 at 22:47 Comment(0)
W
1

There's a little bit more information about the semantics of these errors in RFC 2616, which documents HTTP 1.1.

Personally, I would probably use 400 Bad Request, but this is just my personal opinion without any factual support.

Walden answered 24/12, 2009 at 22:38 Comment(0)
D
0

What exactly do you mean by "validation failure"? What are you validating? Are you referring to something like a syntax error (e.g. malformed XML)?

If that's the case, I'd say 400 Bad Request is probably the right thing, but without knowing what it is you're "validating", it's impossible to say.

Dextroamphetamine answered 24/12, 2009 at 22:38 Comment(1)
what if we are trying to validate some business validation or rules.Stadium
B
0

if you are validating data and data is not, according to defined rules its better to send 422(Unprocessable Entity)so that sender will understand that he braking the rules what agreed upon.

Bad request is for syntax errors. some of the tools like postman shows syntax errors upfront.

Brokenhearted answered 24/12, 2021 at 12:17 Comment(0)
C
0

Here's another interesting scenario to discuss.

What if its an type detection API that for instance accepts as input a reference to some locally stored parquet file, and after reading through some metadata of the blocks that compose the file, may realize that one or more of the block sizes exceed a configured threshold and therefor the server decided the file is not partitioning correctly and refuses to start the type detection process. This validation is there to protect against one of two (or both) scenarios: (1) Long processing time, bad user experience ; (2) Server application explodes with OutOfMemoryError

What would be an appropriate response in this case?

400 (Bad Request) ? - sort of works, generically.

401 (Unauthorized i.e. Unauthenticated) ? - unrelated.

403 (Forbidden i.e. Unauthorized) ? - some would argue it may be somewhat appropriate in this case -

422 (Unprocessable entity) ? - many older answers mention this as appropriate option for input validation failure. What bothers me about using it in my case is the definition of this response code saying its "due to semantic error" while I couldn't quite understand what semantic error means in that context and whether can we consider this failure indeed as a semantic error failure.

Also the allegedly simple concept of "input" as part of "input validation" can be confusing in cases like this where the physical input provided by the client is only but a pointer, a reference to some entity which is stored in the server, where the actual validation is done on data stored in the server (the parquet file metadata) in conjunction with the action the client tries to trigger (type detection).

413 (PayloadTooLarge)? Going through the different codes I encounter one that may be suitable in my case, one that no one mentioned here so far, that is 413 PayloadTooLarge which I also wonder if it may be suitable or again, not, since its not the actual payload sent in the request that is too large, but the payload of the resource stored in the server.

Which leads me to thinking maybe a 5xx response is more appropriate here.

507 Insufficient Storage ? If we say that "storage" is like "memory" and if we also say that we're failing fast here with a claim that we don't have enough memory (or we may blow out with out of memory trying) to process this job, then maybe 507 can me appropriate. but not really.

My conclusion is that in this type of scenario where the server refused to invoke an action on a resource due to space-time related constraints the most suitable response would be 413 PayloadTooLarge

Chopine answered 4/1, 2022 at 20:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.