Website Down? The Exact Checklist to Diagnose and Fix It
Your website is down. A triage runbook: confirm it's real, isolate DNS vs TLS vs server vs app with actual commands, and keep users informed.
Want this checked continuously?
CompleteStatus grades your headers, SSL and email security 24/7 — free, commercial use allowed.
Your website is down, or at least someone says it is. The next fifteen minutes go one of two ways: methodical layer-by-layer isolation that finds the fault fast, or panicked tab-switching, cache-clearing and server-rebooting that makes things worse. The difference is having a runbook before you need one. Here is one: confirm the outage is real, then walk the stack from DNS to TLS to server to application, with the actual commands at each step.
Step 0: Confirm it's actually down
"Down for me" and "down" are different incidents. Before touching anything:
- Check from outside your network. Your office DNS, VPN, or a poisoned local cache can make a healthy site look dead. Load it from your phone on mobile data, or run a check from an external vantage point; the free uptime test requests your URL from outside and shows the status code, response time and any error.
- Check the specific failing URL, not just the homepage. "The site is down" often means one route, one asset host, or one API endpoint.
- Ask what changed. A deploy, a DNS edit, a certificate renewal, an infrastructure migration in the last 24 hours is the prime suspect. Start there before starting from scratch.
If external checks pass and only you can't reach it, you have a local/network problem, not an outage. Otherwise, work down the stack.
Step 1: DNS — does the name resolve?
If DNS is broken, nothing after it matters.
dig +short example.com A
dig +short example.com AAAA
No answer, or the wrong IP? Compare what different resolvers say:
dig +short example.com @1.1.1.1
dig +short example.com @8.8.8.8
- Both return nothing: check your zone at the DNS provider for a deleted record or a broken zone edit, and check whether (worst case) the domain has expired at the registrar. Also verify the delegation:
dig +short example.com NSshould list your actual nameservers. - Resolvers disagree: a recent DNS change is still cached; old records live until TTL expiry, so lower TTLs ahead of planned changes.
- Wrong IP entirely: either a fat-fingered record or, if you didn't change anything, treat it as possible hijacking and check your registrar/DNS-provider account immediately.
DNS resolves correctly? Next layer.
Step 2: TLS — does the handshake succeed?
An expired or misconfigured certificate blocks every browser at the door while your server sits there perfectly healthy.
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates -subject -issuer
Check three things:
notAfterin the past → expired certificate. Renew, and then reload the web server, since a renewed cert on disk does nothing until nginx/Apache reloads it.- Subject/SAN doesn't cover the hostname → hostname mismatch (classic after adding a subdomain or moving behind a new load balancer).
- The handshake itself fails (connection refused/reset on 443) → the web server or load balancer isn't listening; that's a server-layer problem, keep going.
A quicker read on all of this: the free SSL checker reports expiry, chain and hostname match in one shot. If this step is how you found out the cert expired, set up expiry monitoring after the incident. This failure mode is entirely preventable, and with maximum certificate lifetimes now down to 200 days, renewals happen more often than they used to.
Step 3: Server — does anything answer?
Now talk to the server directly and read the response headers:
curl -sv -o /dev/null https://example.com
curl -I https://example.com
Interpret what you get:
- Connection timed out → the host is unreachable: crashed instance, firewall/security-group change, or a provider outage. Check your cloud console and the provider's status page.
- Connection refused → the machine is up but nothing listens on the port: web server crashed or was stopped. SSH in;
systemctl status nginx(or apache2/caddy) and restart if dead. - 502 Bad Gateway / 504 Gateway Timeout → the proxy is alive but the app behind it isn't answering: crashed app process, exhausted PHP-FPM/worker pool, or a hung upstream.
- 503 Service Unavailable → deliberate maintenance mode left on, or an overloaded backend shedding load.
- 500 Internal Server Error → the app is running and failing. That's the next layer.
Step 4: Application — it answers, but wrongly
The server responds; the application is the problem. On the box:
- Read the error log first, not the code.
tail -100your app and web-server error logs; the actual exception is usually sitting right there. - Check disk space:
df -h. A full disk produces a lot of weird, unrelated-looking failures (sessions, logs, database writes all failing at once). - Check the database: is the process up, are connections being refused, did it hit
max_connections? - Check the last deploy. If the timeline matches, roll back first and diagnose second. Reverting to known-good beats debugging under fire.
While you fix it: communicate
Silence during an outage costs more trust than the outage. If you have a status page, use it within the first few minutes: acknowledge ("We're investigating elevated errors"), update as you learn, and post when resolved. A short honest update beats a detailed one that arrives an hour late, and it holds off the flood of support tickets so you can work the problem.
Afterward: the 30-minute post-incident review
Same week, while memory is fresh, write down four things: what happened (timeline), how you found out (a monitor, or a customer? If it was a customer, that's finding #1), what fixed it, and what would have prevented or shortened it. Turn the last answer into tickets. One process fix per incident adds up quickly.
Get paged before your customers notice
Every step above assumes you know the site is down. The teams that recover fastest are alerted by a machine within minutes, ideally with the failing layer already identified. CompleteStatus checks your site continuously, confirms failures with a second probe before alerting (far fewer 3 AM false alarms), and monitors each layer of this runbook separately: DNS records, certificate expiry and validity, response codes, keywords and response times, plus status pages for the communication step, so much of the diagnosis above is done before you open a terminal.
Run the free uptime test to check any site right now, then set up monitoring free (10 monitors on the free tier, commercial use allowed) so the next incident starts with an alert, not an angry email.
Written with AI assistance and reviewed by the CompleteStatus team.
Get notified when CompleteStatus opens
New accounts are closed while we're in private beta. Leave your email and we'll send one message the moment sign-ups open — nothing else.