What a browser hides from you
Open a site in a browser and you see one thing: the page, or an error. Everything that happened on the way is discarded — the redirects, the codes, the certificate the server presented, how long it thought before answering. That discarded part is where nearly every "the site is slow" and "it works for me" argument is actually decided.
This check makes each step visible. It follows the redirect chain one hop at a time rather than letting an HTTP client resolve it silently, records the status code, the address that answered and the time for every hop, then reports the certificate and the headers of whatever it ended up at.
Redirect chains, and why three hops is two too many
A redirect is not free. Each one is a full round trip — a DNS lookup if the hostname changed, a TCP handshake, a TLS handshake, a request, a response — before any content is transferred. On a fast connection a hop costs tens of milliseconds; on mobile, where latency dominates, it can cost several hundred.
The classic accidental chain looks like this, and almost nobody builds it deliberately:
http://example.com/page→ 301 →https://example.com/page— the HTTPS rulehttps://example.com/page→ 301 →https://www.example.com/page— the canonical-host rulehttps://www.example.com/page→ 301 →https://www.example.com/page/— the trailing-slash rule
Three separate rules, each perfectly sensible on its own, applied in the worst possible
order. The fix is to make the first redirect land on the final destination — send
http://example.com/page straight to https://www.example.com/page/
— which collapses three hops into one without changing any of the rules' intent.
The codes matter as much as the count:
- 301 and 308 — permanent
- Search engines transfer ranking signals to the target and browsers cache the redirect, sometimes for a very long time. A 301 issued by mistake is unusually painful to undo, because visitors who already have it cached keep following it.
- 302 and 307 — temporary
- Nothing is transferred, nothing is cached long-term. Correct for genuinely temporary situations, wrong for a permanent move — a permanent move served as 302 leaves the old URL competing with the new one indefinitely.
- The 307/308 distinction
- 301 and 302 historically allowed clients to change a POST into a GET when following them, and browsers do exactly that. 307 and 308 forbid it: method and body are preserved. If a form submission mysteriously arrives empty after a redirect, this is why.
Reading the status code you land on
The final code is the server's own summary of what happened. The ones worth recognising on sight:
- 200 — the page was returned. Note that this says nothing about the page being correct: plenty of sites return 200 with an error message in the body, which is invisible to monitoring that only checks the code.
- 403 — the server understood and refused. Very often not about you at all: bot filtering, geographic blocking, or a rule aimed at datacentre addresses. If you see 403 here but the site loads in your browser, that is the most likely explanation.
- 404 and 410 — not found, and deliberately gone. The difference is intent, and search engines treat 410 as a stronger signal to drop the URL.
- 429 — you are being rate limited. Honest and useful; the server is telling you to slow down rather than pretending to be broken.
- 500 — the application crashed. The problem is in the site's own code, and its error log will have the details.
- 502 and 504 — the front-end server could not get a usable answer from the application behind it. 502 means the answer was invalid or the connection was refused; 504 means there was no answer in time. Both point behind the web server, not at it — this is the single most useful distinction in the whole list when something is down.
- 503 — deliberately unavailable: maintenance mode, or overload protection. Should carry a
Retry-Afterheader, and usually does not.
The certificate, and the failure browsers hide
We deliberately do not verify the certificate the way a browser does — we fetch it, then check it separately and report the result. That is the only way to describe a broken certificate instead of just failing to connect and calling it a network error.
Three things are worth reading in the result, and they are independent of each other:
- Does the chain verify? This catches the most expensive quiet failure in TLS: a server that does not send its intermediate certificate. Browsers paper over it — they cache intermediates from other sites and can fetch missing ones — so the site looks perfect to the person who set it up. Meanwhile
curl, Java applications, Android devices and payment callbacks all fail with "unknown authority", and the owner spends a week insisting it works. - Does the name match? A certificate covers a specific list of names.
example.comandwww.example.comare two different names, and a wildcard covers exactly one label —*.example.comdoes not covera.b.example.com. - How long is left? Certificate lifetimes have been shrinking for years and automated renewal is now the norm, which means expiry is no longer a calendar problem but a monitoring problem: renewal fails silently, and nobody notices until the certificate runs out. Anything under two weeks on an automated setup means the automation has stopped working.
Security headers: what each one actually prevents
We report which of these the server sends and what value it sends. We do not grade the result, because whether a given header is needed depends on the site — a static brochure page and an online bank have different correct answers.
- Strict-Transport-Security
- Tells the browser to use HTTPS for this host for the stated period, without asking. It closes the gap where a visitor's first request goes out over plain HTTP and can be intercepted. Treat
preloadwith care: getting on the preload list is quick, getting off it is slow, and until then every subdomain must work over HTTPS forever. - Content-Security-Policy
- Restricts where scripts, styles and frames may load from. The most effective defence against cross-site scripting there is, and the most work to deploy, because it breaks anything you forgot to list. Roll it out in report-only mode first.
- X-Content-Type-Options: nosniff
- Stops the browser guessing a file's type from its contents when the declared type disagrees. Without it, an uploaded file the server calls plain text can be executed as script. One line, no side effects, nothing to configure — there is no good reason to omit it.
- X-Frame-Options and frame-ancestors
- Both stop your page being embedded in someone else's frame, which is what clickjacking needs.
frame-ancestorsinside CSP is the modern form and takes precedence; the old header remains for very old clients. - Referrer-Policy
- Controls how much of the current URL is sent along when a visitor follows a link out. Defaults are reasonable now, but if your URLs contain identifiers or tokens, this is what stops you leaking them to every site you link to.
- Permissions-Policy
- Declares which browser capabilities — camera, microphone, geolocation — the page and anything it embeds may use. Most useful as a way to say "nothing here needs any of this".
Timing: thinking versus sending
We report two numbers because one cannot answer the question. Time to first byte is how long the server took to start answering — that is the database, the application, the cache miss. Total time includes transferring the response, which is bandwidth and page size. A site with a first byte at 900 ms and a total of 950 ms has a slow application; one with 80 ms and 2 s has a heavy page. The remedies have nothing in common, and a single "load time" figure hides which one you have.
What this check cannot tell you
We fetch the page once, from one place, with a user agent that identifies this tool. A site behind a CDN may answer us from a different edge than it answers you. A site that filters datacentre traffic may give us a 403 it would never give a visitor. And we read only the HTML the server returns — nothing is executed, so a page that assembles itself in JavaScript will look emptier here than it does in a browser.
If the response looks wrong, the next question is usually where the problem sits. DNS records tell you whether the name points where you think it does, a port check tells you whether anything is listening at all, and ping tells you whether the host is reachable in the first place.