Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The way I think of the status codes is as instructions for how a generic HTTP client or proxy should or may behave in response. Any status code which, in practice, does not affect generic client behavior, does not need to be distinguished in the status code (and can instead be distinguished in the body of the response).

For example, status 412 can be thought of as "try the transaction over again, your information about the resource is out of date". Maybe your client has generic support for atomic operations on resources, and 412 controls that. 429 can be thought of as "slow down". If your client has built-in throttling, 429 controls that.

> There is no useful distinction between different kindes of bad requests (syntactically wrong, structurally wrong, not applicable to the data found, etc.)

In general, a bad request is not something that client software would be expected to handle, other than "don't expect a different result if you try again". Obviously this is not a hard and fast rule because some errors are truly transient and some servers give the wrong error code due to bugs or whatever.

You could go all WebDAV with status 422 for non-syntactic errors, but I am skeptical of its utility. If your action is not applicable to the resource, you have 405.

When there's a 400 error, the expected client response is "some programmer will come by and look at the logs if it turns out to be a problem".

> Special handling is needed to test if a resource exists -- you cannot just GET it and check for a 404 code because browsers log all 404 as errors, even if it's the "happy path"

This is more of a UX issue with the browser console than any problem with HTTP.

> The error codes confuse authentication and authorization

Eh, it could be worse. We also have misspelled headers like "referer". As long as clients and semantics use the correct semantics, I don't care.



> You could go all WebDAV with status 422 for non-syntactic errors, but I am skeptical of its utility.

FastAPI uses 422 for "your data is structured wrong for this schema" and it's better than sliced bread.

I think the worst part about the 4xx/5xx distinction is that it doesn't really tell you whether the request is failing in a transient or permanent way (or can't tell). It would have been nice to have more leading digits (6xx, 7xx) and make some distinctions:

- the client did something wrong but might be able to succeed later if state changes (403, 404, 429)

- the client did something wrong and the result is unlikely to change without changing the request (405, 422)

Same with the 5xxs, split into "server" (endpoint) failed, vs middleware (load balancers, etc) failed or is overloaded.


Yes, maybe the distinction would be nice, but I think the existing 4xx and 5xx codes provide a reasonable baseline for building smart clients.

403, 404—log error, maybe retry later. I don’t think there’s a reasonable way for the server to distinguish transient vs permanent failures here.

429—client should back off, throttle requests.

5xx—client should back off, throttle requests.

The big problem here is that from the server side, if you try to figure out whether an error is transient or permanent, you often get the wrong answer. It’s a diabolical problem. The distinction between “failed” and “overloaded” is something that you might figure out in a post-mortem once humans take a look, but while it is happening, I would not expect the two to be distinguished.

What I do want to transmit from server to client are things like:

- Try again at a different URL (307).

- Try again at a different URL, and update your config to point at this other URL (301, 308).

- The request should be authenticated (401). Try again if you can authenticate.

- I understood the request and had the resources to process it, but the request failed (403, 404, 405, 412, etc) due to the system state. Retry if the user asks for it.

- There is something wrong with the request itself (400, 422, etc). This is a bug, get a programmer to look at it.

- Slow down (429). Retry automatically, but not too quickly.

- As above, but take a look at the server or proxy to see if it’s working correctly. (503, 504)

- Go look at the server logs. (500)

As a rule, I would say that any error can be transitory, and I would tend to write clients with the ability to retry any request. Not as a hard rule, just as a tendency. A “permanent” status code isn’t necessarily a statement of fact, but just a belief.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: