Website Not Loading: Server-Side Checklist
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://ipfyi.com/iframe/guide/website-not-loading/" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://ipfyi.com/guide/website-not-loading/
Add a dynamic SVG badge to your README or docs.
[](https://ipfyi.com/guide/website-not-loading/)
Use the native HTML custom element.
A systematic server-side checklist for diagnosing why a website is not loading, from DNS propagation to SSL errors and reverse proxy misconfigurations.
A Systematic Approach to Website Downtime
When a website is not loading, the failure can originate at any layer: DNS resolution, TCP connectivity, TLS negotiation, application server, database, or CDN. Jumping to conclusions wastes time. Instead, work through each layer from the outside in, ruling out causes as you go.
DNS Propagation Check
Before assuming a server problem, confirm that DNS is resolving correctly. DNS changes can take up to 48 hours to propagate globally, though most propagate within minutes with low TTLs.
# Query your authoritative nameserver directly (bypass caching)
dig yourdomain.com @ns1.yourdomain.com
# Compare with what resolvers see
dig yourdomain.com @8.8.8.8 # Google
dig yourdomain.com @1.1.1.1 # Cloudflare
dig yourdomain.com @9.9.9.9 # Quad9
# Check if the A record matches your expected IP
dig +short yourdomain.com
# Verify from multiple global locations
# Use https://dnschecker.org or https://whatsmydns.net
Common DNS problems:
| Problem | Symptom | Fix |
|---|---|---|
| Missing A record | NXDOMAIN |
Add A record in DNS panel |
| Wrong IP in A record | Connection refused or wrong site | Update A record |
| Stale cache | Some locations see old IP | Wait for TTL expiry, or lower TTL proactively |
| NS delegation broken | SERVFAIL |
Check domain registrar's nameserver settings |
HTTP Response Analysis
Once DNS resolves correctly, test the HTTP layer directly.
# Get full HTTP response including headers
curl -v https://yourdomain.com
# Follow redirects and show final response
curl -L -v https://yourdomain.com 2>&1 | head -50
# Check HTTP without TLS (to isolate TLS issues)
curl -v http://yourdomain.com
# Get just the status code
curl -o /dev/null -s -w "%{http_code}" https://yourdomain.com
# Include timing information
curl -w "\nDNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\n" \
-o /dev/null -s https://yourdomain.com
Interpreting status codes:
| Code | Meaning | Common Cause |
|---|---|---|
| 200 | OK (but page may error) | Content issue |
| 301/302 | Redirect loop | Check redirect chain with curl -L |
| 400 | Bad Request | Malformed request or Host header issue |
| 403 | Forbidden | Permissions, WAF block, or IP block |
| 502 | Bad Gateway | Backend (Gunicorn/uWSGI) is down |
| 503 | Service Unavailable | App crashed or overloaded |
| 504 | Gateway Timeout | Backend too slow, not backend not running |
SSL/TLS Handshake
SSL errors prevent the browser from loading the page at all. Use openssl s_client to diagnose.
# Full TLS handshake debug
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com
# Check certificate expiry
echo | openssl s_client -connect yourdomain.com:443 2>/dev/null \
| openssl x509 -noout -dates
# Test specific TLS version
openssl s_client -connect yourdomain.com:443 -tls1_2
openssl s_client -connect yourdomain.com:443 -tls1_3
# Check certificate chain completeness
openssl s_client -connect yourdomain.com:443 -showcerts 2>/dev/null \
| grep -E "^(subject|issuer)"
Common TLS issues:
- Certificate expired: Renew with Certbot (
sudo certbot renew) - Incomplete chain: Server missing intermediate certificate
- Wrong domain: Certificate issued for
wwwbut not apex domain (or vice versa) - Self-signed cert: Replace with a CA-signed certificate
- SNI not configured: Nginx
server_namedirective missing
Server Resource Exhaustion
A site can become unreachable when the server runs out of CPU, memory, disk space, or file descriptors.
# Memory: look for OOM kills
sudo dmesg | grep -i "oom\|killed process" | tail -20
free -h
# CPU load
uptime
top -b -n 1 | head -20
# Disk space (full disk causes many silent failures)
df -h
du -sh /var/log/* | sort -rh | head -10
# Open file descriptors (approaching system limit = connection drops)
cat /proc/sys/fs/file-max
lsof | wc -l
# Check if the application process is running
systemctl status nginx
systemctl status gunicorn # or your app server
ps aux | grep -E 'nginx|gunicorn|uwsgi|node'
If memory is exhausted, check for memory leaks in application workers or consider restarting the service as an immediate mitigation while investigating.
Reverse Proxy Misconfiguration
When Nginx or Apache sits in front of your application, misconfiguration is a common cause of 502/504 errors.
# Test Nginx configuration syntax
sudo nginx -t
# Check Nginx error log
sudo tail -50 /var/log/nginx/error.log
# Check if upstream (Gunicorn/uWSGI) is listening
ss -tlnp | grep :8000 # or whatever port your app uses
curl http://127.0.0.1:8000/ # test the backend directly
# Verify upstream block in nginx config
grep -r "upstream\|proxy_pass" /etc/nginx/sites-enabled/
Example correct Nginx proxy configuration:
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 10s;
proxy_read_timeout 60s;
}
}
Common mistakes: missing proxy_set_header Host, wrong port in proxy_pass, socket file permission errors, or proxy_read_timeout too short for slow database queries.
CDN Cache Issues
If you use Cloudflare, Fastly, or another CDN, a cached error response can make a site appear down even after the origin is fixed.
# Check if you're hitting CDN or origin
curl -v https://yourdomain.com 2>&1 | grep -E "cf-ray|x-cache|age|server"
# Cloudflare cache status
# cf-cache-status: HIT (served from cache)
# cf-cache-status: MISS (fetched from origin)
# cf-cache-status: BYPASS (origin served directly)
# Check if origin is healthy (bypass CDN)
# Find origin IP from Cloudflare dashboard, then:
curl -H "Host: yourdomain.com" http://ORIGIN_IP/
# Purge Cloudflare cache via API
CF_ZONE_ID="your_zone_id"
CF_TOKEN="your_api_token"
curl -X POST "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/purge_cache" \
-H "Authorization: Bearer ${CF_TOKEN}" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
Browser Developer Tools
When everything checks out server-side but the page still does not display correctly in a browser, use DevTools:
- Network tab: Shows all resource requests. Look for red rows (failed requests), timing waterfalls, and blocked requests.
- Console tab: JavaScript errors can prevent page rendering.
- Security tab (Chrome): Shows certificate details and mixed-content warnings.
- Hard refresh: Press
Ctrl+Shift+R(Windows/Linux) orCmd+Shift+R(Mac) to bypass browser cache.
# Simulate different clients with curl
# Mobile user agent
curl -A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0)" https://yourdomain.com
# Check for mixed content (HTTP resources on HTTPS page)
# Use browser console or:
grep -r "http://" /var/www/yourdomain/templates/ # for static links
Always test from multiple networks and devices before concluding the issue is global — sometimes a problem is specific to one ISP, one country, or one browser version.