Guide
HTTP status codes explained
The code is the server telling you who has the problem. It is worth reading carefully.
The first digit is the whole summary
Every status code is three digits, and the first one carries most of the meaning. Before learning any individual code it is worth internalising the five classes, because they answer the only question that matters when something breaks: whose problem is this?
| Class | Name | Meaning | Commonly seen |
|---|---|---|---|
| 1xx | Informational | The request was received; processing continues | Rarely seen directly — 101 for WebSocket upgrades |
| 2xx | Success | The request succeeded | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirection | Further action is needed to complete it | 301, 302, 304 Not Modified, 308 |
| 4xx | Client error | The request was wrong | 400, 401, 403, 404, 429 |
| 5xx | Server error | The request was fine; the server failed | 500, 502, 503, 504 |
The 4xx/5xx split is the one people get backwards under pressure. A 4xx means the request was wrong and repeating it unchanged will fail again. A 5xx means the request was fine and the server did not manage to answer it — retrying the identical request is entirely reasonable, and is what a well-behaved client does with backoff.
The pairs that get confused
Most practical confusion comes down to six pairs. Each pair looks similar and points somewhere completely different.
| Pair | The difference | Why it matters |
|---|---|---|
| 301 vs 302 | Permanent vs temporary | 301 is cached hard and transfers ranking; 302 is not and does not |
| 401 vs 403 | Unauthenticated vs unauthorised | 401 invites you to log in; 403 says logging in will not help |
| 404 vs 410 | Not found vs deliberately gone | 410 tells a crawler to stop asking; 404 leaves it retrying |
| 500 vs 502 | This server failed vs the one behind it failed | 500 points at the application; 502 at the proxy-to-app link |
| 502 vs 504 | Invalid response vs no response in time | 502 often means the app is down; 504 that it is too slow |
| 429 vs 503 | You sent too much vs the server is unavailable | Both may carry Retry-After; 429 is about you, 503 is not |
301 is close to permanent, and that is the point
Browsers treat a 301 as licence to stop asking. Chrome and Firefox will cache one for a very long time, and the visitor's browser will keep following it after you have removed it from the server — because it never sends the request that would learn about the change.
That makes 301 the right code for a genuine move and a costly one for anything provisional. A maintenance page, an A/B test, a temporary regional redirect: all of those want 302 or 307. The rule of thumb is simple — if you might want the original URL back, do not use 301.
307 and 308 exist because of a real bug
Historically, browsers receiving a 301 or 302 in response to a POST would re-issue the follow-up request as a GET, silently discarding the body. That behaviour was so widespread it became expected, and it could not be fixed without breaking the web.
So two new codes were added with the same semantics and one guarantee: 307 is a temporary redirect and 308 a permanent one, and both preserve the method and body. If you are redirecting anything other than a GET, those are the codes you want.
Reading a failure from the outside
When a site fails, the status code and the response headers together usually identify the layer that failed before you have access to any logs.
A 502 or 504 with a Server header naming nginx or a
CDN tells you the proxy is healthy and what is behind it is not. A 500 with an application
framework's fingerprint tells you the request reached the application and it threw. A 403 from a CDN with no application header at all is usually a WAF rule rather than anything your code
did.
Redirect chains are worth following in full rather than only looking at the final code. A chain that goes HTTP to HTTPS to www to a trailing slash is four round trips before anything is served, each paying full latency, and it is invisible if you only inspect the destination.
Codes worth serving deliberately
410 Gone for content you have removed on purpose. It tells crawlers to stop asking, where a 404 leaves them retrying for months.
429 Too Many Requests with a Retry-After header, rather than dropping
connections. It converts an outage into a well-behaved queue.
503 Service Unavailable during maintenance, again with Retry-After. Returning 200 with a maintenance page tells search engines your site is now a maintenance
page, and they will index it.
The general principle behind all three: the status code is machine-readable and the page body is not. Getting the code right is what lets every automated client — crawler, CDN, monitor, library — do the right thing without a human reading the page.
Frequently asked questions
What is the real difference between 301 and 302?
Permanence, and it has consequences. A 301 says the resource has moved for good: browsers cache it aggressively, sometimes indefinitely, and search engines transfer ranking signals to the new URL. A 302 says the move is temporary, so nothing is cached long and the original URL keeps its signals. Sending a 301 during a temporary maintenance redirect is a genuinely painful mistake, because visitors’ browsers will keep following it long after you have reverted the server.
Why do I get 403 when I am definitely logged in?
Because 401 and 403 answer different questions. 401 means "I do not know who you are" — authenticate and try again. 403 means "I know exactly who you are and you may not do this". Being logged in and getting 403 is therefore consistent: your identity was accepted and your permissions were not. If you get 403 while anonymous, the server has decided not to reveal that authentication would help.
Is 404 bad for SEO?
A 404 for a page that genuinely does not exist is correct and harmless — it is the honest answer, and search engines handle it routinely. What causes damage is a soft 404: returning 200 with a "not found" page. That tells a crawler the page exists and has content, so it stays in the index as a low-quality result. Returning the right status code matters more than avoiding the code.
What does 502 tell me that 500 does not?
Where the failure is. A 500 means the server that answered you hit an error in its own code. A 502 means the server you reached is a proxy, it forwarded your request to something behind it, and that something gave an invalid response or none at all. 500 points at the application; 502 points at the connection between the proxy and the application — very often that the application is not running.
When should an API return 400 rather than 422?
400 for a request the server cannot parse or that violates the protocol — malformed JSON, a missing required parameter, a header that makes no sense. 422 for a request that parsed perfectly and asked for something invalid — a well-formed date that falls in the past where a future date is required. In practice the distinction is inconsistently applied and 400 is widely used for both; the important thing is being consistent within one API.
Why does my browser show a cached redirect I have already removed?
Because a 301 is cacheable and many browsers cache it for a very long time, sometimes until the profile is cleared. The redirect no longer exists on the server, and the browser never asks. Clearing the site’s data fixes it locally; for everyone else the practical remedy is to keep serving the destination and to be extremely deliberate about issuing 301s in the first place.
Try it yourself
Everything above is easier to follow against a real answer.
- HTTP Headers Checker See the response headers, redirects and security headers a URL returns.
- SSL Certificate Checker Inspect a site’s TLS certificate, expiry date, issuer and SANs.
- Port Checker Check whether a TCP port is open and reachable on a public host.
- DNS Checker Look up A, AAAA, CNAME, MX, TXT, NS, SOA and CAA records for any domain.