Question
How to fix Cloudflare 521 web server down
521 usually means Cloudflare reached your origin IP but the connection was refused.
First checks
- Confirm your web process is running.
- Confirm 80/443 are listening on origin.
- Check firewall and cloud security groups for edge IP blocks.
Run this command set first
# Service health
sudo systemctl status caddy --no-pager -n 40
sudo systemctl status nginx --no-pager -n 40
# Listener check
sudo ss -lntp | grep -E ':80|:443'
# Firewall and security controls
sudo ufw status
sudo iptables -S | head -n 120
# Direct origin reachability from another host
curl -I --connect-timeout 8 http://ORIGIN_IP
curl -I --connect-timeout 8 https://ORIGIN_IP -k
Common 521 root causes
- Service exited after deploy: caddy/nginx crashed or failed config validation.
- No listener on 443: process is alive but TLS port is not bound.
- Firewall drift: inbound allow rules changed and now block edge traffic.
- Host-level overload: process is up but not accepting new connections.
Real-world example: Caddy service is healthy, but port 443 is closed
A common trap is checking only systemctl status caddy. The service can be active while the host firewall still rejects Cloudflare's connection.
sudo systemctl status caddy --no-pager -n 20
sudo ss -lntp | grep ':443'
sudo ufw status numbered
# Expected signal when fixed:
# LISTEN 0 4096 *:443 *:* users:(("caddy",pid=1234,fd=9))
# 443/tcp ALLOW Anywhere
If ss shows no listener, fix the web server first. If ss shows a listener but UFW or the cloud security group blocks 443, open the rule and retest through Cloudflare.
Real-world example: Nginx reload accepted a broken upstream
For Nginx sites, 521 can appear after a deploy when the reverse proxy remains installed but the app process behind it is gone or refusing connections.
sudo nginx -t
sudo systemctl status nginx --no-pager -n 20
sudo journalctl -u nginx --since '15 minutes ago' --no-pager | tail -n 80
curl -I http://127.0.0.1:3000
# If the local app port refuses the connection, restart the app process,
# then reload nginx only after the app answers locally.
Do not change Cloudflare SSL settings for this case. A 521 is a connection refusal problem, not a certificate validation problem.
Example: cloud firewall blocks Cloudflare edges
If Caddy or Nginx listens correctly but Cloudflare still shows 521, check the cloud security group before editing application config. This is common after tightening inbound rules to a small office IP range.
# On the origin
sudo ss -lntp | grep -E ':80|:443'
sudo ufw status verbose
# From another machine, force a direct origin test
curl -I --connect-timeout 8 http://ORIGIN_IP
curl -Ik --connect-timeout 8 https://ORIGIN_IP
# If direct origin works from your IP but Cloudflare returns 521,
# verify the cloud firewall allows inbound 80/443 from Cloudflare edge IP ranges.
When using a cloud firewall, avoid allowing only your own IP unless Cloudflare is set to DNS-only. For proxied records, Cloudflare edge servers must be able to connect to the origin. After changing the rule, retest /, /robots.txt, and one content URL through the proxied hostname.
How to confirm recovery
- Cloudflare-proxied homepage returns
200/301consistently. /robots.txtand/sitemap.xmlstop returning 521.- No repeated connection refused errors in service logs for recent checks.
What to monitor for the next hour
After the site is back, watch crawler-facing files first. A browser homepage test is not enough if Cloudflare still fails on /robots.txt, /sitemap.xml, or important guide pages.
for path in / /robots.txt /sitemap.xml; do
curl -I --max-time 10 "https://example.com$path"
done
sudo journalctl -u caddy --since '1 hour ago' --no-pager | grep -i 'refused\|listen\|error'
sudo journalctl -u nginx --since '1 hour ago' --no-pager | grep -i 'refused\|connect\|upstream'
If the homepage recovers first but crawler files still fail, check whether a path-level firewall, cache rule, or maintenance route is treating static files differently from application routes.
Do not confuse 521 with crawler blocking
If only GPTBot, OAI-SearchBot, or another crawler gets blocked while normal browsers receive 200, that is usually a WAF or bot-management rule, not a 521 incident. A real 521 is an edge-to-origin connection refusal and should affect ordinary Cloudflare-proxied requests too.
If origin is reachable but Cloudflare still reports an unknown error, continue with Cloudflare 520 unknown error.
If origin is reachable but slow under load, continue with Cloudflare 522 timeout troubleshooting.