Rectangle 27 1

REST HTTP status codes for failed validation or invalid duplicate?


FYI - RFC description of 422: 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.

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.

WebDAV is a HTTP extension. "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)" So, status code 422 is not a http status code, but a status code of an extions of http.

What, no 418 I'm A Teapot in the registry? I'm shocked, shocked!

deamon, that doesn't make sense. HTTP defines how to define new codes, and that's what WebDAV is doing. There's a status code registry for a reason.

Note
Rectangle 27 1

REST HTTP status codes for failed validation or invalid duplicate?


FYI - RFC description of 422: 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.

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.

WebDAV is a HTTP extension. "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)" So, status code 422 is not a http status code, but a status code of an extions of http.

What, no 418 I'm A Teapot in the registry? I'm shocked, shocked!

deamon, that doesn't make sense. HTTP defines how to define new codes, and that's what WebDAV is doing. There's a status code registry for a reason.

Note
Rectangle 27 1

REST HTTP status codes for failed validation or invalid duplicate?


Bad request is definitely the most common response to this kind of issue. The only other alternative is 422 Unprocessable Entity. It actually comes from WebDav but it is perfectly valid to reuse any status code that has been registered with IANA.

For input validation failure: 400 Bad Request + your optional description. This is suggested in the book "RESTful Web Services". For double submit: 409 Conflict

I disagree with your interpretation of RFC7231, although it states something perceived to be a client error, all the examples given in this paragraph are violations of HTTP protocol, not logical errors: syntax, framing, routing. Thus, I consider that HTTP spec does not allow 400 for failed validation on application level.

So how do you differentiate between malformed data that the server can't even parse, and a validation error? A client would handle these two responses completely differently. For validation, they'd likely display the errors to the user. For truly "malformed data", they would log the error so the the bug in the method that generates the request could be fixed.

So it might have been argued that it was inappropriate for semantic errors. But not any more; since June 2014 the relevant standard RFC 7231, which supersedes the previous RFC2616, gives the use of 400 (Bad Request) more broadly as

The relevant specification used to be RFC2616, which gave the use of 400 (Bad Request) rather narrowly as

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

Yes, the request body is part of the syntax.

the server cannot or will not process the request due to something that is perceived to be a client error

Note
Rectangle 27 1

REST HTTP status codes for failed validation or invalid duplicate?


Bad request is definitely the most common response to this kind of issue. The only other alternative is 422 Unprocessable Entity. It actually comes from WebDav but it is perfectly valid to reuse any status code that has been registered with IANA.

For input validation failure: 400 Bad Request + your optional description. This is suggested in the book "RESTful Web Services". For double submit: 409 Conflict

I disagree with your interpretation of RFC7231, although it states something perceived to be a client error, all the examples given in this paragraph are violations of HTTP protocol, not logical errors: syntax, framing, routing. Thus, I consider that HTTP spec does not allow 400 for failed validation on application level.

So how do you differentiate between malformed data that the server can't even parse, and a validation error? A client would handle these two responses completely differently. For validation, they'd likely display the errors to the user. For truly "malformed data", they would log the error so the the bug in the method that generates the request could be fixed.

So it might have been argued that it was inappropriate for semantic errors. But not any more; since June 2014 the relevant standard RFC 7231, which supersedes the previous RFC2616, gives the use of 400 (Bad Request) more broadly as

The relevant specification used to be RFC2616, which gave the use of 400 (Bad Request) rather narrowly as

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

Yes, the request body is part of the syntax.

the server cannot or will not process the request due to something that is perceived to be a client error

Note
Rectangle 27 1

REST HTTP status codes for failed validation or invalid duplicate?


FYI - RFC description of 422: 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.

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.

WebDAV is a HTTP extension. "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)" So, status code 422 is not a http status code, but a status code of an extions of http.

What, no 418 I'm A Teapot in the registry? I'm shocked, shocked!

deamon, that doesn't make sense. HTTP defines how to define new codes, and that's what WebDAV is doing. There's a status code registry for a reason.

Note
Rectangle 27 1

REST HTTP status codes for failed validation or invalid duplicate?


Bad request is definitely the most common response to this kind of issue. The only other alternative is 422 Unprocessable Entity. It actually comes from WebDav but it is perfectly valid to reuse any status code that has been registered with IANA.

For input validation failure: 400 Bad Request + your optional description. This is suggested in the book "RESTful Web Services". For double submit: 409 Conflict

I disagree with your interpretation of RFC7231, although it states something perceived to be a client error, all the examples given in this paragraph are violations of HTTP protocol, not logical errors: syntax, framing, routing. Thus, I consider that HTTP spec does not allow 400 for failed validation on application level.

So how do you differentiate between malformed data that the server can't even parse, and a validation error? A client would handle these two responses completely differently. For validation, they'd likely display the errors to the user. For truly "malformed data", they would log the error so the the bug in the method that generates the request could be fixed.

So it might have been argued that it was inappropriate for semantic errors. But not any more; since June 2014 the relevant standard RFC 7231, which supersedes the previous RFC2616, gives the use of 400 (Bad Request) more broadly as

The relevant specification used to be RFC2616, which gave the use of 400 (Bad Request) rather narrowly as

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

Yes, the request body is part of the syntax.

the server cannot or will not process the request due to something that is perceived to be a client error

Note
Rectangle 27 1

REST HTTP status codes for failed validation or invalid duplicate?


  • Failed validation: 403 Forbidden ("The server understood the request, but is refusing to fulfill it"). Contrary to popular opinion, RFC2616 doesn't say "403 is only intended for failed authentication", but "403: I know what you want, but I won't do that". That condition may or may not be due to authentication.
  • Trying to add a duplicate: 409 Conflict ("The request could not be completed due to a conflict with the current state of the resource.")

"10.4.4 403 Forbidden The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead." I see no emphasis there ("SHOULD/SHOULD NOT" are RFC 2119 keywords, not emphasis); that's your idea what "forbidden" means, not RFC's.

@deamon: That is not the specification, that's Wikipedia, i.e. someone's opinion on "what HTTP status codes mean"; note that the page essentialy says "this is what Apache means with 403, this is what IIS means with 403", and nowhere does it reference the official RFC. You seem to be repeating "403 means whatever Apache says". NOT. The actual RFC (which is the relevant document, not Apache's implementation, not IIS' implementation, not anyone else's implementation) is here: w3.org/Protocols/rfc2616/rfc2616-sec10.html

For the error message itself you should modify the reason phrase, so sending the header HTTP/1.0 403 Form validation errors is the cleanest way to go.

I like this answer, but still see one small problem. According to the spec, when a 403 is returned, "the request SHOULD NOT be repeated". However, returning a 409 "is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request". In the case of a duplicate, I think 403 is then more appropriate, as you cannot really resolve the conflict (except by deleting the previous instance of the resource).

IMO, 422 "Unprocessable Entity" makes much more sense. My reasoning is that it's not that the server refuses to fulfill request, it's that the server can't fulfill the request.

You should definitely give a more detailed explanation in the response headers and/or body (e.g. with a custom header - X-Status-Reason: Validation failed).

Note
Rectangle 27 1

REST HTTP status codes for failed validation or invalid duplicate?


  • Failed validation: 403 Forbidden ("The server understood the request, but is refusing to fulfill it"). Contrary to popular opinion, RFC2616 doesn't say "403 is only intended for failed authentication", but "403: I know what you want, but I won't do that". That condition may or may not be due to authentication.
  • Trying to add a duplicate: 409 Conflict ("The request could not be completed due to a conflict with the current state of the resource.")

"10.4.4 403 Forbidden The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead." I see no emphasis there ("SHOULD/SHOULD NOT" are RFC 2119 keywords, not emphasis); that's your idea what "forbidden" means, not RFC's.

@deamon: That is not the specification, that's Wikipedia, i.e. someone's opinion on "what HTTP status codes mean"; note that the page essentialy says "this is what Apache means with 403, this is what IIS means with 403", and nowhere does it reference the official RFC. You seem to be repeating "403 means whatever Apache says". NOT. The actual RFC (which is the relevant document, not Apache's implementation, not IIS' implementation, not anyone else's implementation) is here: w3.org/Protocols/rfc2616/rfc2616-sec10.html

For the error message itself you should modify the reason phrase, so sending the header HTTP/1.0 403 Form validation errors is the cleanest way to go.

I like this answer, but still see one small problem. According to the spec, when a 403 is returned, "the request SHOULD NOT be repeated". However, returning a 409 "is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request". In the case of a duplicate, I think 403 is then more appropriate, as you cannot really resolve the conflict (except by deleting the previous instance of the resource).

IMO, 422 "Unprocessable Entity" makes much more sense. My reasoning is that it's not that the server refuses to fulfill request, it's that the server can't fulfill the request.

You should definitely give a more detailed explanation in the response headers and/or body (e.g. with a custom header - X-Status-Reason: Validation failed).

Note
Rectangle 27 1

REST HTTP status codes for failed validation or invalid duplicate?


  • Failed validation: 403 Forbidden ("The server understood the request, but is refusing to fulfill it"). Contrary to popular opinion, RFC2616 doesn't say "403 is only intended for failed authentication", but "403: I know what you want, but I won't do that". That condition may or may not be due to authentication.
  • Trying to add a duplicate: 409 Conflict ("The request could not be completed due to a conflict with the current state of the resource.")

"10.4.4 403 Forbidden The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead." I see no emphasis there ("SHOULD/SHOULD NOT" are RFC 2119 keywords, not emphasis); that's your idea what "forbidden" means, not RFC's.

@deamon: That is not the specification, that's Wikipedia, i.e. someone's opinion on "what HTTP status codes mean"; note that the page essentialy says "this is what Apache means with 403, this is what IIS means with 403", and nowhere does it reference the official RFC. You seem to be repeating "403 means whatever Apache says". NOT. The actual RFC (which is the relevant document, not Apache's implementation, not IIS' implementation, not anyone else's implementation) is here: w3.org/Protocols/rfc2616/rfc2616-sec10.html

For the error message itself you should modify the reason phrase, so sending the header HTTP/1.0 403 Form validation errors is the cleanest way to go.

I like this answer, but still see one small problem. According to the spec, when a 403 is returned, "the request SHOULD NOT be repeated". However, returning a 409 "is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request". In the case of a duplicate, I think 403 is then more appropriate, as you cannot really resolve the conflict (except by deleting the previous instance of the resource).

IMO, 422 "Unprocessable Entity" makes much more sense. My reasoning is that it's not that the server refuses to fulfill request, it's that the server can't fulfill the request.

You should definitely give a more detailed explanation in the response headers and/or body (e.g. with a custom header - X-Status-Reason: Validation failed).

Note
Rectangle 27 1

REST HTTP status codes for failed validation or invalid duplicate?


If you want to treat a duplicate request as a warning or notification rather than as an error, a response status code of 304 Not Modified and Content-Location header identifying the existing resource would be just as valid. When the intent is merely to ensure that a resource exists, a duplicate request would not be an error but a confirmation. The request is not wrong, but is simply redundant, and the client can refer to the existing resource.

In my opinion, @Piskvor's answer is the more obvious choice to what I perceive is the intent of the original question, but I have an alternative that is also relevant.

In other words, the request is good, but since the resource already exists, the server does not need to perform any further processing.

It was my understanding that 304 is intended for GET operations to assist with caching.

Status Code 304 Not Modified would also make an acceptable response to a duplicate request. This is similar to processing a header of If-None-Match using an entity tag.

Note