Every HTTP response carries a three-digit status code. It is the server’s one-word summary of what happened: did the request succeed, redirect, fail on the client, or fail on the server. Read the first digit and you know the category; read all three and you know the specifics. Most debugging sessions start here, so it pays to know what each code actually claims.
This guide walks the five classes and the codes that matter in each. For any individual code, the HTTP status code reference lists them all with one-line meanings.
The five classes
The leading digit sorts every response into one of five groups. 1xx is informational, 2xx is success, 3xx is redirection, 4xx is a client error, and 5xx is a server error. That split is the most useful thing to memorize, because it tells you which side of the connection to investigate. A 4xx says “your request was wrong.” A 5xx says “my server broke.” Getting that direction right saves time.
1xx: informational
These are interim responses; the real answer is still coming, and you rarely see them in logs. 100 Continue tells a client that sent an Expect: 100-continue header that it may proceed with the request body. 101 Switching Protocols is returned when upgrading a connection, most commonly to WebSocket.
2xx: success
200 OK is the everyday success code for a request that returned a body. 201 Created is the correct response after a POST that made a new resource; a well-behaved API also returns the new resource’s URL in a Location header. 204 No Content means the request succeeded but there is deliberately no body, ideal for a DELETE or a form submission that needs no response payload. Returning 200 with an empty body where 204 belongs is a small but common inconsistency.
3xx: redirection
Redirects tell the client to look elsewhere, and the exact code matters. 301 Moved Permanently says the resource has a new home for good. 302 Found says it is temporarily somewhere else, so keep using the original URL. The subtle trap: historically both let clients switch a POST to a GET when following the redirect. 307 Temporary Redirect and 308 Permanent Redirect fix that ambiguity by preserving the original method and body. Use 307/308 when a POST must stay a POST across the redirect.
304 Not Modified is the odd one out: a caching response. The client sent a conditional request with If-None-Match or If-Modified-Since, and the server confirms the cached copy is still fresh, so no body is sent. Seeing many 304s means caching is working, not a problem.
4xx: client errors
The request reached the server, but something about it was wrong. 400 Bad Request is the generic “I could not parse or accept this.” 404 Not Found means the resource does not exist at that path. 409 Conflict signals that the request clashes with current state, such as creating something that already exists or a version mismatch on an edit. 422 Unprocessable Entity means the syntax was fine but the content failed validation, the right code for valid JSON with a bad field value. 429 Too Many Requests means you hit a rate limit; check for a Retry-After header.
401 versus 403
These two get confused constantly. 401 Unauthorized actually means unauthenticated: the server does not know who you are, so supply or refresh credentials. It is usually paired with a WWW-Authenticate header. 403 Forbidden means the server knows exactly who you are and you still may not have this resource. Retrying 401 with valid credentials can succeed; retrying 403 with the same identity will not. So a 403 from a login flow means the user is authenticated but lacks permission, while a 401 means the credentials did not land.
5xx: server errors
Now the fault is on the server side. 500 Internal Server Error is the catch-all for an unhandled exception; it tells you nothing except “something threw.” 502 Bad Gateway means a proxy or load balancer got an invalid response from the upstream it depends on. 503 Service Unavailable means the server is temporarily unable to handle the request, often during deploys, overload, or maintenance, and may include a Retry-After. 504 Gateway Timeout means a proxy waited for an upstream response and gave up. The 502/504 pair almost always points behind the front door: an app server that crashed, is slow, or is unreachable.
301 vs 302 for SEO
For search, the choice between 301 and 302 is not cosmetic. A 301 tells crawlers the move is permanent, so they transfer ranking signals to the new URL and eventually drop the old one from the index. A 302 tells them the original is still canonical, so they keep indexing the old URL and may not pass signals forward. If you permanently moved a page but used 302, you can quietly leak ranking equity for months. When a move is final, use 301.
Reading them in practice
When you are debugging a raw request, the status line and headers hold most of the story. Pasting a saved command into the curl parser breaks out the method, URL, and headers so you can see exactly what was sent, and the URL parser splits a messy endpoint into its parts. Pair those with the status class and you can usually name the problem before reading the logs.