Skip to content

HTTP status codes

An HTTP response begins with a three-digit code and a short reason phrase. The first digit is the whole summary: 1xx is provisional, 2xx succeeded, 3xx points somewhere else, 4xx blames the request, 5xx blames the server. If you remember only that, you can read a log you have never seen before.

The reason phrases here are the ones from the RFCs, in English, because that is what travels on the wire — a server sends "Not Found", not a translation of it, and a phrase you are grepping for in a log has to match the bytes that were actually sent.

The distinctions that cause real trouble are inside the classes rather than between them: 401 versus 403, 301 versus 308, and 502 versus 503 each answer a different question about what to do next, and each is routinely used for the other.

1xx — Informational

3

Provisional: the response is not final and another one follows.

CodeReason phraseWhat it means
100ContinueHeaders received, keep sending the body.
101Switching ProtocolsSwitching protocols — the WebSocket handshake.
103Early HintsEarly hints: preload these resources while the real response is prepared.

2xx — Success

5

The request was received, understood and accepted.

CodeReason phraseWhat it means
200OKSuccess, with a body.
201CreatedCreated.Should carry a Location header pointing at the new resource.
202AcceptedAccepted for processing, which has not happened yet.
204No ContentSuccess, and deliberately no body.The right answer to a DELETE, or a save with nothing to return.
206Partial ContentPartial content — the answer to a Range request. Resumable downloads.

3xx — Redirection

6

The resource is elsewhere, or your cached copy is still good.

CodeReason phraseWhat it means
301Moved PermanentlyMoved permanently. Update your links; caches may keep this forever.
302FoundFound — a temporary redirect.Widely implemented as switching the method to GET, which 307 fixes.
303See OtherSee other: fetch the result with GET. The redirect after a form POST.
304Not ModifiedNot modified — your cached copy is current. Sent with no body.
307Temporary RedirectTemporary redirect, method and body preserved.
308Permanent RedirectPermanent redirect, method and body preserved.

4xx — Client error

14

The request is the problem. Repeating it unchanged will fail again.

CodeReason phraseWhat it means
400Bad RequestThe server could not parse the request at all.
401UnauthorizedNot authenticated — the server does not know who you are.Named Unauthorized, but it means unauthenticated. Should include WWW-Authenticate.
403ForbiddenAuthenticated and still not allowed. Better credentials will not help.
404Not FoundNo such resource, and the server will not say whether there ever was one.
405Method Not AllowedWrong method for this URL.Must list the ones that work in an Allow header.
406Not AcceptableNothing available in a format your Accept header will take.
409ConflictConflicts with the current state — an edit against a stale version.
410GoneGone: it existed and was deliberately removed. Stronger than 404.
413Content Too LargeThe body is larger than the server accepts.
415Unsupported Media TypeThe server does not handle this Content-Type.
418I'm a teapotI'm a teapot. A 1998 April Fools' joke, permanently reserved.
422Unprocessable ContentParsed correctly, contents invalid — a missing field, a bad value.
429Too Many RequestsRate limited.Look for Retry-After before retrying, and back off exponentially.
451Unavailable For Legal ReasonsBlocked for legal reasons. The number is a nod to Fahrenheit 451.

5xx — Server error

6

The request may be fine. These are the ones worth retrying.

CodeReason phraseWhat it means
500Internal Server ErrorAn unhandled error on the server. Nothing to fix on your side.
501Not ImplementedThe server does not implement this method at all.
502Bad GatewayA proxy reached the upstream server and got something unusable back.
503Service UnavailableDeliberately not serving — overloaded or in maintenance.The status that should carry Retry-After.
504Gateway TimeoutA proxy gave up waiting for the upstream server.
505HTTP Version Not SupportedThe HTTP version in the request is not supported.

FAQ

What is the difference between 401 and 403?
401 Unauthorized means the request was not authenticated — the server does not know who you are, and a correct 401 includes a WWW-Authenticate header telling you how to prove it. 403 Forbidden means it knows exactly who you are and you still may not have this. Retrying a 403 with better credentials for the same identity will not help.
Should I use 301 or 308 for a redirect?
308 if the method matters. Historically 301 and 302 were widely implemented as "redirect and switch to GET", which silently turns a POST into a GET. 307 and 308 were introduced to promise the method and body are preserved. For a permanent move of a page that is only ever fetched, 301 remains the best-understood choice.
What does 422 mean that 400 does not?
400 Bad Request means the server could not understand the request at all — malformed JSON, a broken header. 422 Unprocessable Content means it parsed fine and the contents are wrong anyway: a well-formed body with a missing required field or a date in the past. The split is useful precisely because the client's fix is different in each case.
Is 418 a real status code?
It is real in that it is registered and every HTTP library knows it, and a joke in that it comes from the 1998 April Fools' Hyper Text Coffee Pot Control Protocol. Attempts to reclaim the number for practical use were rejected, so it is permanently reserved for teapots.
Why is 503 different from 502?
502 Bad Gateway means a proxy reached the upstream server and got something unusable back. 503 Service Unavailable means the server itself is deliberately not serving right now — overloaded, or in maintenance — and it is the one that should carry a Retry-After header, because it is the one that is expected to recover.