Understanding HTTP Status Codes in 2026: From 200 to 500 Explained

Every request on the web gets a three-digit answer back, and most people only ever recognize one of them: 404. Yet each number carries a precise statement. Is the thing gone for good, or just moved? Are you locked out, or simply not signed in? Is the fault yours or the server’s? This article sorts the five status-code classes, explains the codes that actually matter day to day – and shows why the wrong code can cost your API and your SEO dearly.

The five classes: what the first digit tells you

An HTTP status code is a three-digit number the server sends back as part of every response. Since June 2022 the authoritative definition lives in RFC 9110 (“HTTP Semantics”), which consolidates rules that were previously spread across several documents. The binding list of all assigned codes is maintained by IANA in its HTTP Status Code Registry.

What matters is the first digit, because it sets the class: 1xx is informational (the request is still in progress), 2xx means success, 3xx is a redirect, 4xx marks an error on the client side – you or your browser – and 5xx means the fault is on the server. That coarse split alone gets 90 percent of all cases into the right bucket.

The 1xx class rarely shows up directly. The interesting one is 103 Early Hints: it lets a server send pointers to resources that should be preloaded while it is still assembling the real response. The rest of this article is about the codes you see every day.

2xx: success is not just success

The best-known code is 200 OK: the request succeeded, the response holds the data you wanted. For simple GET calls that is the right choice. But “successful” can be expressed more precisely, and in APIs that distinction pays off.

201 Created belongs at the end of a successful POST that created a new resource – a new user, a new order. The response should also carry a Location header pointing to the address of the freshly created resource. A client then knows immediately where to find the new object, without guessing.

204 No Content is the signal “it worked, but there is nothing to return.” Typical after a DELETE or a PUT where the client already knows the new state anyway. The empty body is intentional. Sending a 200 with null instead forces clients into needless special cases.

3xx: 301, 302, 307 and 308 are not interchangeable

Redirects look identical from the outside – the browser lands on a different URL – but they differ on two counts: is the redirect permanent or temporary, and may the HTTP method change along the way?

301 Moved Permanently says: the resource has moved for good, remember the new address. Search engines transfer ranking value to the target, and browsers sometimes cache the redirect aggressively. 302 Found instead means “temporarily elsewhere,” and the old URL stays canonical. Historically both share a problem: many clients wrongly turn a POST into a GET during the redirect.

That is exactly what the newer codes fix. 307 Temporary Redirect is the clean temporary counterpart to 302 and guarantees that method and body survive – a POST stays a POST after the redirect. 308 Permanent Redirect (RFC 9110, section 15.4.9) is the method-preserving equivalent of 301. Rule of thumb: for permanent page moves use 301; if the method must be preserved, use 308 or 307.

Redirect chains: the quiet SEO killer

A single redirect is cheap. It gets problematic when redirects pile up: the old HTTP page 301s to HTTPS, which in turn points to the www variant, which then redirects again to a new URL structure. Each hop costs an extra round trip and thus load time.

For search engines such chains are doubly harmful. Google does follow multiple redirects, but it stops after a certain number, and every hop risks diluting the signals. Even more expensive are redirect loops, where two URLs redirect to each other – the browser then aborts with an error and the page is no longer reachable at all.

The fix is unspectacular: always redirect straight to the final target, not to the next waypoint. When you add a new redirect, check whether the target itself already redirects, and shorten the chain to a single hop.

304 Not Modified: the code that saves bandwidth

304 Not Modified is not an error but an efficiency signal. The client asks: “Has this resource changed since my last visit?” If not, the server answers with 304 and an empty body – the browser pulls the file from its cache. That saves transfer volume, especially for large images or scripts.

Technically it works through conditional requests. On the first visit the server sends an ETag (a fingerprint of the content) or a Last-Modified date. On the next call the browser sends that value back in the If-None-Match or If-Modified-Since header. If the fingerprint still matches, you get the 304.

401 versus 403: signed in, or allowed?

These two codes are constantly confused, even though their meanings are clearly separate. 401 Unauthorized actually means “not authenticated”: the server does not know who you are. A valid sign-in or token is missing. The correct response: provide credentials, then ask again. A 401 is required to carry a WWW-Authenticate header telling you how to authenticate.

403 Forbidden instead means “not authorized”: the server knows exactly who you are – but you still may not. A logged-in user trying to pull up someone else’s invoice correctly gets a 403. Signing in again does not help, because the problem is permissions, not identity.

The mnemonic: 401 = “I don’t know who you are,” 403 = “I do, and the answer is no.” For security reasons some applications deliberately return 404 instead of 403 so as not to reveal that a protected resource exists at all.

404 versus 410: gone, or gone for good?

404 Not Found is the classic: there is nothing at this URL. The code deliberately leaves open why – maybe the page never existed, maybe it is temporarily offline, maybe you mistyped. For search engines it means: “I might come back later.”

410 Gone is the harder, more honest variant: the resource existed but was deliberately and permanently removed and will not return. Google removes 410s from the index faster than 404s because the statement is less ambiguous.

For everyday use that means: for typos and unknown paths, 404 is right. If instead you deliberately take content down and want it out of search results quickly, 410 is the fitting choice.

429: when you knock too fast

429 Too Many Requests is the rate-limiting code. The server says: “You have sent too many requests in too short a time, slow down.” APIs use it to protect themselves against overload and abuse.

Ideally a 429 carries a Retry-After header giving, as a number of seconds or a date, when you may try again. A well-built client reads that header and waits exactly that long – instead of hammering on and triggering the limit even longer. Anyone repeatedly hitting 429s should use exponential backoff: wait longer after each failure (1, 2, 4, 8 seconds), ideally with a bit of randomness so clients do not all restart at once.

Many APIs also send headers like X-RateLimit-Remaining, which tell you how many requests you have left in the current window – useful for pacing a bulk job before you ever hit a 429.

5xx: the fault is on the server

As soon as the first digit is a 5, you usually did nothing wrong. 500 Internal Server Error is the catch-all: something went wrong somewhere in the server code, an unhandled exception, a bug. The code only says “broken,” not “why” – the cause is in the server logs.

The other three point at the infrastructure in front, typically a reverse proxy or a gateway. 502 Bad Gateway: the gateway received an invalid response from the backend – often because the backend process crashed. 503 Service Unavailable: the service is temporarily unavailable, for example due to maintenance or overload; a Retry-After header fits well here.

504 Gateway Timeout finally means: the gateway waited, but the backend did not answer in time – usually because of a slow database query or a hanging external call. The distinction helps debugging: 502 points to a crash, 504 to slowness – two entirely different problems.

418 and other curiosities

418 I’m a teapot comes from an April Fools’ RFC from 1998, the “Hyper Text Coffee Pot Control Protocol”: a teapot asked to brew coffee duly answers with 418. The code is officially marked as reserved at IANA and still appears as an Easter egg in many frameworks.

Other curiosities are 451 Unavailable For Legal Reasons – a nod to Ray Bradbury’s novel “Fahrenheit 451,” used for legally blocked content – and 402 Payment Required, which sat reserved for decades and is only slowly finding real use with payment APIs. The point behind them: once you grasp the logic of the system, a three-digit number tells you more than three paragraphs of error text.

In practice: set the right codes and hunt bugs

When you build an API, the status code is part of the interface, just as important as the JSON. A common beginner mistake: answer everything with 200 and stuff the real state into a field like "error": true. That forces every client to parse the body before it knows whether something failed, and it blinds monitoring to errors.

Set the codes semantically instead: 400 for broken input, 401/403 for auth problems, 404 for things not found, 422 for data that is syntactically valid but semantically wrong, 201 after creating. That way any HTTP client understands your answer without special knowledge.

For debugging, the fastest path is the command line: curl -I https://example.com shows only the headers plus status code, and curl -IL additionally follows all redirects, exposing redirect chains. In the browser the network tab does the same and colors 4xx/5xx red – a glance tells you whether the fault sits with you or the server.

How tools on CalcSI help

If you deal with HTTP responses regularly, keep the lookup reference HTTP Status Codes handy: it lists every code with its class and meaning, without paging through the RFC. When a broken URL or a Location header hides an encoded parameter, the URL Encoder/Decoder makes it readable so you can see where a redirect truly points. When an API response comes back nested and unformatted, the JSON Formatter brings structure to it so you spot error objects and fields at a glance. And when you want to search log files for particular status codes – say all 5xx lines – build the matching pattern like \s5\d{2}\s with the Regex Tester and check it against sample text. All four run entirely in the browser.

Comments