A status code checker returns one number. Ask for four.
Paste a URL into a status code checker and you get a number. It is accurate, it is instant, and on its own it answers almost nothing, because a number is the least ambiguous and least informative part of an HTTP response.
Four things alongside it turn the same request into a diagnosis.
One: every hop, not the last one
Most checkers report the final status after following redirects. A URL that answers 200 at the end may have passed through four hops to get there, and each hop is latency for the visitor and a dilution of signals for a crawler.
curl -sSIL https://example.com/ | grep -iE '^(HTTP/|location:)'
That prints the code and the destination of every step. What you are looking for is a chain longer than one, a mix of permanent and temporary codes in the same chain, a hop from HTTPS back down to HTTP before returning, and any loop.
The last one has a specific shape worth recognising: two hops that point at each other, usually a trailing-slash rule and a canonical-host rule that disagree. Browsers stop after a limit and report too many redirects. A checker that follows to a maximum and reports the final code may report something misleading instead.
Two: the URL you actually ended up at
curl -sSIL -o /dev/null -w '%{num_redirects} hops, %{http_code}, %{url_effective}\n' https://example.com/page
A 200 at a different address than the one you asked for is not the same result as a 200 at the address you asked for. The common cases are a language redirect sending you somewhere based on your address, a mobile variant, and a missing page silently redirecting to the homepage instead of returning 404, which is the single most damaging redirect pattern a site can have.
That last one answers 200, at the wrong URL, which no status-based check will ever flag: the error that looks like a success.
Three: the headers
The status line is one line of the response. The rest is frequently where the answer is.
Server naming a proxy or a load balancer you did not know was in front of the site. A cache header telling you whether you reached the origin at all, which decides whether the 200 you just received says anything about the application. X-Robots-Tag, which can carry an indexing directive that is invisible in the page source. Content-Type, because a stylesheet being served as HTML is a broken page that returns 200 for every asset.
curl -sS -o /dev/null -D - https://example.com/
Four: the size of the body
One number, and it separates two situations that share a status code.
curl -sS -o /dev/null -w '%{http_code} %{size_download}\n' https://example.com/
A 200 with zero bytes is a fatal error with output suppressed. A 200 with a few hundred bytes where you expect fifty thousand is an empty template or a listing that returned nothing. A 200 with the right size is the only one of the three that resembles a working page, and even then it is a weak claim: what a healthy code proves, and what it does not.
The codes a checker calls errors and should not
Three normal states get reported as failures, and treating them as failures is how a team learns to ignore the tool.
A staging site behind HTTP authentication answers 401 permanently and is working correctly, because a demand for credentials is a refusal to serve rather than a failure: what the server means by 401 rather than 403. The alert worth having is the day it answers 200, because a staging copy open to the world ends up competing with the client's real site.
A URL deliberately retired should answer 410, and the interesting event is it coming back as 200 after somebody restored a backup.
A maintenance window should answer 503. The alert is the 503 that is still there an hour after the window closed.
None of that is expressible in a tool that assumes 200 is the only acceptable answer, which is most of them.
Why a checker sometimes disagrees with your browser
Three reasons, in order of how often they turn out to be it.
It sent a HEAD request. Most checkers do, because it is cheaper. A number of applications handle HEAD on a different code path, or not at all, and answer 405 or 500 to a request a real visitor would never make. Re-run it as a GET before concluding anything.
Its user agent is not a browser. Bot management, a firewall rule or a caching layer can serve a challenge page, a redirect, or a 403 to a request that does not look like a person. The site is fine for humans and broken for your checker, which is a real thing to know about and not a fault in the site.
It came from somewhere else. Geographic redirects, consent walls that only appear for some regions, and address-based blocking all produce a different response for a probe in another country than for you.
Which cuts both ways, and is the reason a checker is genuinely useful: it is a second opinion from outside your network, on a path you did not take.
The one-off and the ongoing are different jobs
Typing an address into a box, for a domain you may not manage, with no setup, is a job nothing beats. Keep one bookmarked.
Watching a site you are paid to look after is a different exercise that runs unattended for years, needs to know what this particular page contains when it is healthy, and has to be told which status is expected rather than assuming 200. A one-off checker cannot become that by running it more often.
If you want the four things above for a single address right now, without configuring anything, put it through the checker here. It reads the body as well as the status line, which is the part that decides whether the number means anything.
Every code named here is defined in RFC 9110, section 15, titled simply “Status Codes”, which is the specification rather than a reading of it. Read on 3 August 2026.