999 Request Denied
http.dev
http.dev
> It will also be returned if there are too many HTTP requests in a single day. This is similar to the HTTP 429 Too Many Requests error message.
Similar? That is excatly what 429 was made for, or not? This is weird or just lazy.
Obviously it’s bad practise to do this but I don’t think it’s a mystery why they’d want their denial to be opaque. I’m also having trouble getting that worked up about it. If its OK to return 418 as a joke it’s probably fine to return 999 to suspected crawlers.
Again I’m not really defending the practise, I think it’s bad, I can just clearly see how they ended up where they ended up.
I think if you don't want to supply even that, a better way would be to just close the connection and don't send anything back at all.
The only practical reason for a 999 error code I see is if you want to confuse the client about whether or not the response indicates an error at all. Maybe they were hoping some crawlers treat everything that's not 4xx or 5xx as "success" and so they can poison their index?
That thinking would be relatively naive though, as I think most http clients treat everything that's not 2xx as an error.
So most likely reason is probably some programmer that went through the REST fanboy phase and thought they were special.
I think this is the correct answer if a bad-mannered crawler has been identified. To take it a step further, one could do a HTTP version of a SSH Tarpit[1] although that's likely taking things too far.
If I wanted to mess with clients I don't like, I'd just return a random valid code.
One reason why it's bad is because it violates RFC 2616 (§6.1.1):
The first digit of the Status-Code defines the class of response.
The last two digits do not have any categorization role.
There are 5 values for the first digit:
- 1xx: Informational - Request received, continuing process
- 2xx: Success - The action was successfully received,
understood, and accepted
- 3xx: Redirection - Further action must be taken in order to
complete the request
- 4xx: Client Error - The request contains bad syntax or cannot
be fulfilled
- 5xx: Server Error - The server failed to fulfill an apparently
valid requestRFC 2616 is obsolete, as are the RFCs which obsoleted it; the reference here should be to §15 of RFC 9110.
> Values outside the range 100..599 are invalid. Implementations often use three-digit integer values outside of that range (i.e., 600..999) for internal communication of non-HTTP status (e.g., library errors). A client that receives a response with an invalid status code SHOULD process the response as if it had a 5xx (Server Error) status code.
Yes, in case it wasn't clear, my intent was to correct the reference only, not the substance communicated by the reference.
Controversial and unpopular opinion, but RFC specs went out the window as soon as SPA apps came about.
If I can't use my back button without my page being hijacked to the home page of the site then to me RFCs are now just a defunct recommendation.
The expected client behavior is sending in return an empty http post request with wtf header and value "I feel this server is passive aggressive towards me."
From the examples, this seem to be the point. If you receive a 429, you know you can just backoff a bit and it'll work at a later point, but if you receive 999, you're not sure how to proceed, which seems to be what they (the service) wants.
Given that this seems to be bot-protection, that might actually be the point. It's basically saying; "I don't want you here, don't try to resolve this". Or in other words "F*ck off"
IMO, it should be a simple 403 Forbidden.
Other options for this case:
403 Forbidden is probably the best fit. "The 403 (Forbidden) status code indicates that the server understood the request but refuses to fulfill it."
But it may not sufficiently communicate the "go away forever" aspect. Alternatives might include:
410 (maybe its not actually, strictly gone, but I'm never going to give it to you, so stop asking) Has the benefit of also being a 4xx error so focuses on it being a client error.
301 Moved Permanently Location: file:///dev/null
And there's really no limit. If I'm going to be nonstandard, I could use more than three digits in the error code. I could use hex. I could use full text. The possibilities are limitless.
More likely they just used it because it's one end of the 3 digit range and a "proper" code would leak information to the unwelcome traffic about what they did to get blocked (making it easier to avoid). Apparently some services already use 000 for other purposes (TIL).
I highly doubt this is the origin. I think its just the last three digit number.
Edit: I should not that while you're using it in your Nginx config, you're not _actually_ returning it to the client. That's a fairly important distinction, and I think makes it more appropriate than the 999 thing.
For me, if the server cannot specifically tell you what kind of error happened, it’s by definition a 500.
My API is internal, but it’s been nice to consider, “all 500-level errors are my team’s problem to fix or represent more accurately as a 400-level.”
4xx: "You asked for something in a way that I can't respond" (auth error, unknown path, etc.)
5xx: "You asked for something in a valid way, but I can't respond right now" (outage, bug, etc.)
If you want to respond impolitely, you could just terminate the connection, or send plaintext "Don't scrape me, we are watching you" instead of a HTTP response, but I can imagine that doesn't work properly with proxies and middleware.
The conventional nonsense response "418 I am a teapot" has been standardized unfortunately. But `return Response("Request Denied", status=999)` is easy to write and does the job.
Isn’t that a 403?
I’m not sure what value there is in saying “beep boop” rather than “you can’t come in.” If you really intend what you’re saying, why not just drop the tcp connection without any http response as you suggest?
It says it’s deprecated but we still get them from their API from time to time.
It's a weird enough and unique enough error that I pretty much know what is possibly up the moment I see it.
It’s not. That code does not conform to any standard.
The uses described should very clearly be 403 Forbidden where it’s refusing to respond based on user-agent, and 429 Too Many Requests where it’s rate limiting.
The spec says <https://www.rfc-editor.org/rfc/rfc9110#section-15-6>:
> Values outside the range 100..599 are invalid. Implementations often use three-digit integer values outside of that range (i.e., 600..999) for internal communication of non-HTTP status (e.g., library errors). A client that receives a response with an invalid status code SHOULD process the response as if it had a 5xx (Server Error) status code.
So, the spec declares it invalid, and its suggested handling yields the wrong semantics (server rather than client error).
Given the notes they have on things like 430, I’m astonished at them not noting the problems with this code.
That's precisely why LinkedIn returns 999, they're telling you to bugger off. Nobody thinks this is a good idea.