Continue
Keep sending the request body.
Sent when the client used an Expect: 100-continue header to check the server will accept a large body before uploading it.
RFC 9110
Look up any HTTP status code and what it actually means.
31 of 31 codes
Keep sending the request body.
Sent when the client used an Expect: 100-continue header to check the server will accept a large body before uploading it.
RFC 9110
Protocol is changing at the client’s request.
The handshake response for a WebSocket upgrade.
RFC 9110
Preload hints before the real response.
Lets the browser start fetching stylesheets and scripts while the server is still generating the page.
RFC 8297
The request succeeded.
The default success response. Do not return 200 with an error object inside — clients, caches and monitoring all read the status line, not your payload.
RFC 9110
A new resource was created.
The correct response to a POST that creates something. Include a Location header pointing at the new resource.
RFC 9110
Accepted for processing, not yet done.
For asynchronous work. Return something the client can poll for the eventual result.
RFC 9110
Success, and there is no body.
Ideal for DELETE and for PUT when you do not echo the resource back. A 204 must not include a body — some clients error if one is sent.
RFC 9110
Only part of the resource is returned.
The response to a Range request — how video seeking and resumable downloads work.
RFC 9110
The resource has a new permanent URL.
What SEO migrations need: it transfers ranking signals to the new URL. Browsers cache it aggressively, so a wrong 301 is painful to undo.
RFC 9110
Temporarily at a different URL.
Historically ambiguous: most clients change POST to GET when following it, contrary to the spec. Use 307 or 303 when the method matters.
RFC 9110
Fetch the result with GET.
The correct redirect after a successful POST — it stops a browser refresh from resubmitting the form.
RFC 9110
Your cached copy is still valid.
Sent when the client’s If-None-Match or If-Modified-Since matches. Carries no body, which is the entire point.
RFC 9110
Temporary, and keep the method.
Like 302 but guarantees a POST stays a POST. Prefer it whenever the method must be preserved.
RFC 9110
Permanent, and keep the method.
The 301 equivalent that does not rewrite POST to GET.
RFC 9110
The request itself is malformed.
Reserve it for syntax problems — unparseable JSON, a missing required parameter. For a well-formed request that fails business rules, 422 is more precise.
RFC 9110
You are not authenticated.
Misnamed: it means unauthenticated. Use it when credentials are missing, invalid or expired, and include a WWW-Authenticate header. If the user IS logged in but lacks permission, that is 403.
RFC 9110
Authenticated, but not allowed.
The server knows who you are and is refusing anyway. Re-authenticating will not help. Some APIs return 404 instead to avoid confirming a resource exists.
RFC 9110
No resource at this URL.
Also the polite way to hide a resource from someone not allowed to know it exists.
RFC 9110
Wrong HTTP method for this URL.
The response must include an Allow header listing the methods that are supported.
RFC 9110
Clashes with the current state.
Duplicate creation, or an edit against a stale version. Pair it with ETags for optimistic concurrency.
RFC 9110
Deliberately removed, permanently.
Stronger than 404: it tells crawlers to drop the URL rather than keep retrying it.
RFC 9110
The request body is too big.
Commonly hit at the proxy rather than the app — check nginx client_max_body_size before your handler.
RFC 9110
Wrong Content-Type.
Usually a client sending form-encoded data to an endpoint expecting JSON, or omitting the header entirely.
RFC 9110
A joke from 1998 that never went away.
Defined by the Hyper Text Coffee Pot Control Protocol as an April Fools RFC. Occasionally used as a deliberate "no" to bots.
RFC 2324
Well-formed, but semantically wrong.
The right code for validation failures: the JSON parsed fine, but the email is already taken or the date is in the past.
RFC 9110
Rate limit exceeded.
Include a Retry-After header. Without it, well-behaved clients cannot back off correctly.
RFC 6585
Something broke on the server.
The catch-all for unhandled exceptions. Never leak a stack trace in the body — log it, return an opaque reference the user can quote to support.
RFC 9110
The server does not support this method.
Different from 405: 501 means the method is unrecognised anywhere on the server, not just at this URL.
RFC 9110
An upstream server sent an invalid response.
Almost always the proxy telling you your application crashed, is not listening, or is behind a misconfigured port.
RFC 9110
Temporarily down or overloaded.
The correct code for maintenance windows. Add Retry-After so crawlers come back instead of dropping your pages.
RFC 9110
An upstream server did not answer in time.
The proxy gave up waiting. Distinguish it from 502: the upstream is reachable but slow, not broken.
RFC 9110
Every HTTP status code, with what it means and when to actually return it. Most of the value here is in the distinctions people get wrong — 401 means unauthenticated while 403 means authenticated-but-refused, and a 302 quietly turns a POST into a GET where a 307 would not.
401 means unauthenticated — you have not proved who you are, so credentials are missing, invalid or expired, and the response should carry a WWW-Authenticate header. 403 means authenticated but not permitted: the server knows exactly who you are and is refusing anyway, so retrying with the same credentials will never help. The name 'Unauthorized' for 401 is simply a historical mistake.
Use 400 when the request itself is malformed — unparseable JSON, a missing required field. Use 422 when the request parsed perfectly but fails your business rules: the email is already registered, the date is in the past. The distinction tells the client whether to fix its serialisation or its data.
No. Caches, proxies, monitoring, retry logic and client libraries all read the status line, not your payload. A 200 with {"error": ...} inside will be cached as a success and will not trigger any error handling. Return the status that describes what happened.
Both are permanent. The difference is method preservation: most clients turn a POST into a GET when following a 301, while a 308 guarantees the method and body are kept. For page moves a 301 is standard and is what transfers SEO ranking; for API endpoints that accept POST, use 308.
303 See Other. It tells the client to fetch the result with GET, which means refreshing the resulting page does not resubmit the form. This is the classic post/redirect/get pattern.