HTTP status codes

Every status code, what it means, and when to actually use it.

The five classes

1xx Informational The request was received; the process continues.
2xx Success Received, understood and accepted.
3xx Redirection Further action is needed to complete the request.
4xx Client error The request is faulty. Fixing it is the caller’s job.
5xx Server error A valid request the server failed to fulfil.

31 status codes

CodeNameMeaning
100ContinueKeep sending the request body.
101Switching ProtocolsUpgrading, usually to WebSocket.
103Early HintsPreload hints before the real response.
200OKSuccess. The response body carries the result.
201CreatedA new resource exists. Should include a Location header pointing at it.
202AcceptedQueued for processing; not done yet.
204No ContentSuccess, and there is deliberately no body. The correct reply to a DELETE that worked.
206Partial ContentA byte range, for resumable downloads and video seeking.
301Moved PermanentlyUse the new URL from now on. Cached aggressively and hard to undo — be certain before sending it.
302FoundTemporary redirect. May change the method to GET.
303See OtherFetch the result elsewhere with GET. The correct POST-redirect-GET status.
304Not ModifiedYour cached copy is still good.
307Temporary RedirectLike 302 but the method is preserved.
308Permanent RedirectLike 301 but the method is preserved.
400Bad RequestMalformed — the server cannot parse it.
401UnauthorizedNot authenticated. Misnamed: it means unauthenticated. Authorisation failure is 403.
403ForbiddenAuthenticated, but not allowed.
404Not FoundNo such resource. Also used deliberately to hide the existence of something from unauthorised users.
405Method Not AllowedWrong verb for this URL. Must include an Allow header listing what is permitted.
409ConflictCollides with the current state — an edit conflict, a duplicate key.
410GoneIt existed and was deliberately removed.
413Payload Too LargeThe body exceeds the limit.
415Unsupported Media TypeWrong Content-Type.
418I'm a TeapotAn April Fools joke from 1998 that never went away. RFC 2324. Deliberately never removed from the registry.
422Unprocessable ContentSyntactically valid but semantically wrong — validation failed.
429Too Many RequestsRate limited. Should include Retry-After.
500Internal Server ErrorSomething broke and was not handled.
501Not ImplementedThe server does not support this method at all.
502Bad GatewayAn upstream server returned something invalid.
503Service UnavailableOverloaded or down for maintenance. Should include Retry-After. Use this rather than 500 during a deploy.
504Gateway TimeoutAn upstream server did not answer in time.

How it works

The first digit is the whole story: 2 worked, 3 go elsewhere, 4 you made a mistake, 5 we made a mistake. Clients are required to understand the class even when they do not recognise the specific code, so an unknown 499 is safely treated as a 400.

401 versus 403

The most commonly confused pair, not helped by 401 being named “Unauthorized” when it actually means unauthenticated. Use 401 when the caller has not proven who they are — no token, expired token. Use 403 when you know exactly who they are and they still may not do this.

301 is close to permanent

Browsers cache 301 responses aggressively, sometimes indefinitely, and there is no reliable way to make a client forget one. A mistaken 301 can be effectively irreversible for a user who already received it. Use 302 or 307 unless you are certain.

307 and 308 exist because of a bug in history

Early browsers changed POST to GET when following a 301 or 302, contradicting the specification. Rather than break the web, the standard added 307 and 308 with identical semantics but an explicit guarantee that the method is preserved. Use them when the method matters.

422 versus 400

400 means the server could not parse the request at all — broken JSON, a malformed header. 422 means it parsed perfectly and the contents are wrong: a missing required field, an email that is not an email. The distinction genuinely helps API consumers debug.

503 during deployments

A 503 with a Retry-After header tells clients and crawlers this is temporary, so they should come back rather than de-index your pages. Returning 500 or a 200 with an error page during a deploy is a common and avoidable mistake.

Sources

Definitions follow RFC 9110 (HTTP Semantics, 2022), which supersedes the older RFC 7231 family, plus the IANA HTTP Status Code Registry. And RFC 2324 for the teapot.