Most appropriate HTTP status code for “malformed identifier” - web-services

Given we have a web service that takes numerical identifiers. What is the generally most agreed upon HTTP Status Code for an invalid (non-numerical) identifier?
Valid Resource Identifier
Request: GET http://service.co.uk/resources/123
Response: 200 OK
Valid but Unknown Resource Identifier
Request: GET http://service.co.uk/resources/456
Response: 404 Not Found
Invalid Resource Identifier
Request: GET http://service.co.uk/resources/abc
Response: 400 Bad Request
In the event of an invalid identifier, 404 (Not Found) accurately describes the situation; we failed to locate the resource. However 400 (Bad Request) gives an indication as to why the resource was not found.
RFC 2616
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.
10.4.5 404 Not Found
The server has not found anything matching the Request-URI. No
indication is given of whether the condition is temporary or
permanent. The 410 (Gone) status code SHOULD be used if the server
knows, through some internally configurable mechanism, that an old
resource is permanently unavailable and has no forwarding address.
This status code is commonly used when the server does not wish to
reveal exactly why the request has been refused, or when no other
response is applicable.

That URL is not syntactically incorrect, it's semantically incorrect. It has the correct grammar/structure, but the specific identifier chosen doesn't make any sense. That makes 400 (Bad Request) a bad candidate. If it were /123/resources, you might argue that it's syntactically incorrect, but I bet your framework will reply with a 404 for any paths you don't specify. Even if both were applicable, you should prefer the more specific 404 error. That's what every framework I've ever seen does.
Also, RFC 2616 is out of date. Check out 7230 through 7239 for the most recent iteration.

Related

What http status code should I use when customer configuration is not correct?

I am unsure what http status code to return when a customer calls my API, but the requested action cannot be completed for reasons that the customer can fix.
In this case, the http request itself may be fine, but it will not succeed until the customer logs into the front end and updates their configuration. (I will return a body with some informative message to indicate this.)
Is 412 - Precondition Failed - appropriate for this case?
412 Precondition Failed
The server does not meet one of the preconditions that the requester put on the request.
This statuscode has a spefic meaning. It is about a condition that the client stated in the request, whichthe server was unable to fullfill. Don't use this status code for your scenario.
The only HTTP status code that can be used is 400 Bad Request. It is the catch-all status code for all errors that the client can fix. Since you return detailed information about how the client can do this, the client has everything necessary.
see Wikipedia: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Jetty-9 warning: badMessage: 400 Illegal character

I am using jetty-9.2.2 with CometD-3.0.1. I am seeing below warning in my setup. It comes ~4,5 times in a day.:
2014-08-28 08:50:53.712:WARN:oejh.HttpParser:qtp607635164-15194: badMessage:
400 Illegal character for HttpChannelOverHttp#5946f125{r=1,a=IDLE,uri=-}
There is no details that can be debugged from the warning message. I have already logged a request https://bugs.eclipse.org/bugs/show_bug.cgi?id=443049 to provide detailed warning.
Meanwhile I want to know what is causing this warning? Can I ignore this or some messages are lost because of this?
Change https to http in the url.
I had the same error, then found out it's because my application did not support https, so jetty cannot recognize the https encrypted request.
Update May 2017
For Jetty 9.3+ users, you might see a log message that makes this response code more clear.
See Header parse error after upgrade to Jetty 9.3 for details.
Original Answer
The Bad Message: 400 Illegal Character can occur during parsing of a bad HTTP Request.
That is the HTTP error response that the client sees.
Some (not all) situations in which it can occur.
The EOL is not "\r\n" (CR + LF) (HTTP spec requirement)
The HTTP Method token is either not recognized or has invalid whitespace after it
The HTTP Version is not recognized or has invalid characters
HTTP Header name does not follow spec
HTTP Header value does not follow spec
This message is common on public (internet facing) servers.
You have bad HTTP requests coming in. Why?
A legitimate HTTP client has a bug
A legitimate HTTP client is not following the HTTP spec
A non HTTP client attempted to connect to your server (such as attempting to use non-encrypted HTTP on a SSL/TLS/HTTPS port, or even something as odd as an SMTP/IMAP email client attempting to talk to your HTTP port)
A malicious client is attempting to probe your system for weaknesses
This error can be caused, as it was for me, by a silly little mistake.
When testing on my localhost Jetty instance, I received a very similar 400 Illegal Character message. Then I realized why. I had simply assumed application address on my local Jetty was:
https://localhost:8080
whereas the correct address was unsecured:
http://localhost:8080
No problems after that.
Jetty is cautious about detailed error messages that include user sent data, as these can be part of an attack - even if echo'd just to a terminal.
However, we can do better and log some sanitised data. Acting on the bugzilla
Well, I met this problem because I mistook the "http://" as "https://"

REST Web Service: Acceptable HTTP response content-type when responding with status 4XX (Client Error)

I have been unable to find any documentation in the HTTP specifications that govern whether it is acceptable to generate a HTTP response include a human readable error message (e.g. content-type: text/plain) if an HTTP client has made an invalid HTTP request, and specified a request header that limits the acceptable response content types using an accept header.
Imagine a REST web service client issuing an invalid GET request to "http://myhost/validpath?illegalRequestParameter=rubbish", and including a request header "Accept: application/xml" or "Accept: application/vnd.ms-excel".
The server would respond with an HTTP status code in the 4XX series ("400 Bad Request", in this case). But how would the service be able to convey information to the client about the cause of the error?
I see the following options:
Create a plaintext error message in the HTTP response content.
Set response header "Content-type: text/plain" and include a descriptive error message in the response content. This would, however, break the HTTP client's "Accept" restriction.
Don't include a HTTP response content.
This is clearly valid, but not very helpful to the client that just knows that a "Client Error" occurred but has no way of knowing why (and reporting the reason in a client log file).
Try to coerce an error message into an "Accept'able" MIME type.
This is rarely possible. Even if the error message could be constructed as a valid application/xml type, it would likely break a web service contract (e.g. XML Schema conformance).
My question is: Is the above situation governed by existing HTTP specifications/standards?
References:
HTTP Status Code Definitions: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
HTTP Header Field Definitions http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
If the accept header is 'application/xml', then you should return your error message as xml. It will break the client, but that doesn't matter, the client isn't getting the information they requested anyway. At least the client is able to parse the error message...

Which HTTP status to return on domain data error?

I'm developing a RESTful application that integrates with other webservices.
My question is, which HTTP status should I return if my client posts data that is invalid for one of those webservices? For example, if it posts a name that is invalid for a webservice that my application uses, which of the 4** status codes should I return, considering it's a user input error?
Some considerations I've made, and why I'm not comfortable of using them:
400: The data is invalid, but not the request format itself
403: The server is not refusing to respond, although the data is invalid
406: The error is in a provided parameter, not in the "accept" header
412: The error has nothing to do with "If-Match" header
So, what would you use in this case?
Stick with 400, or have a look at 422 (which may be close to what you need).
In real life, HTTP status codes for REST and other web services can be vague and hard to clearly specify. Things also get interesting if your client is actually talking to a proxy server and that proxy sends back its own status. If there's a problem in your web service (perhaps below your app) you may just get 500.
In the past I would opt for returning 200 and using your own JSON-or-whatever structure for returning error information for your client.

What should be the reponse code when validation errors happen?

I'm implementing an API. The API accepts/returns JSON content type.
Now, suppose that the data submitted by some POST request is not valid, like a missing attribute, or a duplication exists for the same data.
What is the standard HTML response code in that case?
The error lies on the client side, so you want to use a 4xx status code. I'd go with 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.
There are two answers:
If you have submitted a form, just return 200 - OK with HTML explaining why the object was not created.
If you have an API you should use the following
200 OK
When the request was OK and returned the proper data.
201 CREATED
The call was successful and the new object created.
400 BAD REQUEST
Invalid request URI
Invalid HTTP Header
Receiving an unsupported, nonstandard parameter
Receiving an invalid HTTP Message Body
401 UNAUTHORIZED
Authorization problems. E.g. wrong API key, etc.
403 FORBIDDEN
Properly authorized, but not allowed.
404 NOT FOUND
The resource does not exist (e.g. on Read or Update)
405 METHOD NOT ALLOWED
Use in situations that a given REST method is not allowed. E.g. a POST on a single resource, or a DELETE on the entire collection of resources.
409 CONFLICT
When an update fails, send "Conflict" to allow the client side to resolve the conflict themselves and retry.
500 INTERNAL SERVER ERROR
Internal error. This is the default code that is used for all unrecognized errors.
501 NOT IMPLEMENTED
Use for expected, but not yet implemented features.
The closest i can find would be 400 Bad Request.
As Ariejan said you should base your API in the HTTP codes already defined. If you want to send a error message the best way should be not use the HTTP message, but better include the message in the response body, JSON formatted.
422 Unprocessable Entity (see RFC 4918, Section 11.2)