"Site Not Loading" — a calm triage
The most common ticket, and the most panic-inducing. Don't guess. Walk down this ladder from the outside in, and the problem will show itself — usually within a couple of minutes.
Work from the outside in: DNS → reach the server → server is up → app is running → SSL. Don't skip ahead. Each rung tells you whether the problem is above or below it.
First: is it down for everyone, or just them?
Before anything technical, rule out the customer's own network. Ask them to try mobile data instead of wifi, or check the site from a "down for everyone or just me" service. If it works for you but not them, it's their side (their ISP, their router, their browser cache, or a hosts-file entry) — not the server.
Rung 1 — Does the name resolve? (DNS)
dig +short thedomain.com
- Nothing / wrong IP? DNS is the problem. The record is missing, wrong, edited in the wrong place, or still propagating. Go to the DNS and Point a Domain pages.
- Correct server IP? DNS is fine — move down to Rung 2.
Rung 2 — Can you reach the server at all?
# Is the box even alive?
ping thedomain.com
# Is the web port open?
nc -zv thedomain.com 443
nc -zv thedomain.com 80
- Ping works, ports refused/timeout? The server is up but the web server isn't listening, or a firewall is blocking. Rung 3.
- Nothing responds at all? The server may be off, crashed, or the whole IP is firewalled. Check the hosting panel — is the VPS actually running?
Lots of servers block ping (ICMP) on purpose while still serving web traffic fine. Trust the nc port check on 80/443 more than ping.
Rung 3 — Is the web server running and listening?
SSH into the box and check:
# What's listening on the web ports?
sudo ss -tlnp | grep -E ':80|:443'
# Is nginx/apache actually running?
sudo systemctl status nginx # or apache2
# If it's dead, the logs say why
sudo journalctl -u nginx --no-pager -n 50
sudo tail -n 50 /var/log/nginx/error.log
- Nothing listening on 80/443? The web server is stopped or crashed. Start it (
sudo systemctl restart nginx) and read the logs for why it died — usually a bad config edit. Test the config first:sudo nginx -t. - Listening only on
127.0.0.1? The app is bound to localhost, so the outside world can't reach it. It must listen on0.0.0.0. Common with Node/Python apps behind a reverse proxy.
Rung 4 — Is the firewall in the way?
Two firewalls to check — the one on the server, and the cloud provider's.
# On the server
sudo ufw status # ports 80, 443 should be ALLOW
# or
sudo iptables -L -n
Then check the cloud firewall / security group in the hosting panel (DigitalOcean firewall, AWS security group, etc.) — it must allow inbound 80 and 443. This is a very common miss: the server is perfect, but the cloud firewall never allowed the ports.
Rung 5 — App is up but throwing errors
If the page loads but shows 502, 503, or 504, the web server is reachable but the app behind it isn't answering:
| Code | Means | Check |
|---|---|---|
502 Bad Gateway | Reverse proxy can't reach the app | Is the app process running? Right port in the proxy config? |
503 Service Unavailable | App is up but refusing (overloaded, restarting, maintenance) | App logs, resource usage |
504 Gateway Timeout | App took too long to respond | Slow query, stuck process, upstream timeout |
500 Internal Server Error | The app itself crashed on this request | Application logs |
Rung 6 — HTTPS-specific problems
Loads on http:// but not https://, or shows a cert warning? That's SSL, not connectivity. Jump to Add an SSL Certificate — usually an expired cert, a name mismatch, or a Cloudflare redirect loop.
The one-screen decision tree
Key takeaways
- Triage from the outside in — never jump straight to the app.
dig→nc→ss/systemctl→ firewall → app logs → SSL.- Check both firewalls: the server's and the cloud provider's.
- App bound to
127.0.0.1is invisible from outside — needs0.0.0.0. - 5xx = the app; cert warning = SSL; wrong IP = DNS. Let the symptom point you.