HTTP status codes
Every HTTP status code, grouped by class, with the distinctions that actually matter: 301 against 308, 401 against 403, 502 against 504.
Runs in your browser
Click a code to copy it.
The request was received and the process is continuing. Rarely seen by hand.
| Code | Meaning |
|---|---|
| Continue | Carry on sending the request body.Sent in reply to an `Expect: 100-continue` header, so a client can check the server will accept a large upload before sending it. |
| Switching Protocols | The connection is changing protocol, most often to WebSocket. |
| Early Hints | Preliminary headers, so the browser can start fetching assets before the real response. |
The request was received, understood and accepted.
| Code | Meaning |
|---|---|
| OK | It worked. |
| Created | It worked and something new exists, named in the `Location` header. |
| No Content | It worked and there is deliberately nothing to send back.A 204 must have no body. Sending one anyway is a protocol error that some clients handle badly. |
| Partial Content | Part of the resource, in reply to a `Range` request. How video seeking and resumable downloads work. |
What you asked for is somewhere else, or has not changed.
| Code | Meaning |
|---|---|
| Moved Permanently | It has moved for good. Update your links.A 301 or 302 permits a client to turn a POST into a GET on the redirect, and browsers do. Use 308 or 307 if the method must survive. |
| Found | It is temporarily somewhere else. Keep using this address. |
| See Other | Go and GET this other address instead — the usual reply to a completed form. |
| Not Modified | Your cached copy is still good. No body is sent. |
| Temporary Redirect | Temporarily elsewhere, and the method must not change. |
| Permanent Redirect | Permanently elsewhere, and the method must not change. |
The request was wrong, or not allowed. Changing the request may help.
| Code | Meaning |
|---|---|
| Bad Request | The server could not understand the request at all. |
| Unauthorized | You are not authenticated. The server does not know who you are.Misnamed: 401 means unauthenticated. 403 is the one that means unauthorised. A 401 must carry a `WWW-Authenticate` header. |
| Forbidden | The server knows who you are and you still may not have this.Logging in will not help. If the existence of the resource is itself secret, 404 is the safer answer. |
| Not Found | There is nothing at this address.Says nothing about whether it ever existed. Use 410 when you know it is gone for good. |
| Method Not Allowed | The address exists but not for this verb. The reply must list the ones that work. |
| Conflict | The request clashes with the current state — an edit against a newer version, for example. |
| Gone | It existed and has been deliberately removed. It is not coming back. |
| I'm a teapot | An April Fools joke from 1998 that never left. |
| Unprocessable Content | Well-formed, but semantically wrong — valid JSON with an invalid field. |
| Too Many Requests | You are being rate limited. `Retry-After` says when to come back. |
The request was fine. The server failed to handle it.
| Code | Meaning |
|---|---|
| Internal Server Error | Something broke and the server has nothing more specific to say. |
| Not Implemented | The server does not support what was asked of it at all. |
| Bad Gateway | A proxy asked something upstream and got an answer it could not use.The upstream answered badly. 504 means it did not answer in time, and 503 means this server chose not to try. |
| Service Unavailable | Temporarily refusing to serve — overloaded or in maintenance. |
| Gateway Timeout | A proxy waited for something upstream and gave up. |
No status code matches that.
Read the first digit
The class tells you who has the problem and whether retrying is worth anything:
- 1xx — received, still working. You will rarely see one by hand.
- 2xx — it worked.
- 3xx — it is somewhere else, or has not changed.
- 4xx — your request was wrong or not allowed. Sending the same thing again will not help.
- 5xx — the server failed. The same request may well work later.
That last distinction is the useful one when something breaks. A 4xx means stop and look at what you sent; a 5xx means the request was fine and retrying is reasonable.
The pairs people get wrong
401 is misnamed. It means unauthenticated — the server does not know who
you are — and it must carry a WWW-Authenticate header. 403 is the one that
means unauthorised. Logging in fixes a 401 and does nothing for a 403.
403 or 404 for something secret? If the existence of the resource is itself confidential, 404 is the safer answer: a 403 confirms there is something there.
404 says nothing about the past. Use 410 when you know the thing is gone deliberately and permanently — it tells crawlers to stop asking.
502, 503 and 504 are three different failures. The upstream answered badly, this server chose not to try, or the upstream did not answer in time.
Redirects change your method, and that surprises people
301 and 302 permit a client to turn a POST into a GET when it follows the redirect, and every browser does exactly that. If you redirect a form submission with a 302, the body is gone by the time it arrives.
307 and 308 exist precisely to forbid that. They are the same as 302 and 301 respectively, except the method and body must survive. If a redirect carries a POST, use 307 or 308.
303 is the deliberate opposite: it tells the client to switch to GET, which is the correct reply to a completed form so that refreshing the result page does not resubmit it.
418 is real, sort of
418 I'm a teapot comes from an April Fools RFC in 1998 and has never gone
away. It is not a real status code and an attempt to remove it from the
registry was rejected on the grounds that too many people had implemented it.
Servers do occasionally return it for genuine “I will not do that” cases.