,{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"How can my server be up but still return 521?","acceptedAnswer":{"@type":"Answer","text":"The host (VM, container) is running but the web server process is not. The machine accepts SSH and responds to pings, but nothing is listening on port 80 or 443. Use ss -tlnp to confirm."}},{"@type":"Question","name":"Why does 521 happen after a deployment?","acceptedAnswer":{"@type":"Answer","text":"Deployments that restart the web server create a brief window with no process listening. Use zero-downtime strategies: rolling restarts, blue-green deployments, or nginx -s reload."}}]}

Cloudflare Error 521: Web Server Is Down

Quick reference

Code521 Web Server Is Down
CategoryCloudflare Edge Error
Standard HTTP?No โ€” Cloudflare proprietary
Vendor referenceCloudflare documentation

What 521 means

Cloudflare 521 "Web Server Is Down" means Cloudflare's edge servers resolved the origin IP, initiated a TCP connection, and the origin's TCP stack responded โ€” but with a connection refusal. Either the origin sent a TCP RST (reset) packet, or the SYN-ACK never arrived because no process is listening on the expected port.

521 is distinct from 522 (Connection Timed Out). In a 521, the TCP handshake started and was actively refused. In a 522, the TCP SYN was sent but the origin never responded at all โ€” it timed out. Refused connections (521) are faster to diagnose because they confirm the host is reachable but the service is down, while timed-out connections (522) leave ambiguity about whether the host itself is reachable.

The origin host is alive and reachable on the network. The web server process (nginx, Apache, Node.js, Gunicorn, etc.) is not running on the port Cloudflare is connecting to โ€” typically port 80 for HTTP or port 443 for HTTPS.

Step-by-step diagnosis

Step 1 โ€” Check what is listening on ports 80 and 443.

# Linux โ€” show processes listening on TCP ports 80 and 443
ss -tlnp sport = :80 or sport = :443

# Alternative with netstat:
netstat -tlnp | grep -E ':80|:443'

# Example output when nginx IS running:
# LISTEN  0  128  0.0.0.0:443  0.0.0.0:*  users:(("nginx",pid=1234,fd=6))
# Example output when NOTHING is running:
# (empty โ€” no lines)

Step 2 โ€” Check web server process status.

# nginx:
systemctl status nginx
# or: service nginx status

# Apache:
systemctl status apache2   # Debian/Ubuntu
systemctl status httpd     # RHEL/CentOS

# Node.js (via PM2):
pm2 status
pm2 logs --lines 50

# Gunicorn/uWSGI (via systemd):
systemctl status gunicorn

Step 3 โ€” Check system logs for crash evidence.

# Recent system log entries (last 100 lines):
journalctl -u nginx -n 100 --no-pager
journalctl -u apache2 -n 100 --no-pager

# Out-of-memory kills (a common reason processes stop):
dmesg | grep -i "killed process"
journalctl -k | grep "Out of memory"

Step 4 โ€” Test connectivity from outside the origin. Use a tool that is NOT the Cloudflare proxy to test direct origin access. Temporarily pause Cloudflare's proxying on the DNS record (grey-cloud in the dashboard) and test with curl directly against the origin IP:

curl -v --connect-to ::ORIGIN_IP: https://yourdomain.com/
# Or test port 443 directly:
nc -zv ORIGIN_IP 443
# Expected: "Connection to ORIGIN_IP 443 port [tcp/https] succeeded!"
# If 521: "nc: connect to ORIGIN_IP port 443 (tcp) failed: Connection refused"

Fixes by cause

Web server process stopped: Restart the service and configure it to start automatically on boot:

# nginx:
systemctl restart nginx
systemctl enable nginx

# Apache:
systemctl restart apache2
systemctl enable apache2

# If the restart fails, check the config for syntax errors:
nginx -t
apachectl configtest

Cloudflare IPs blocked by firewall: Get the current Cloudflare IP list and allowlist all ranges:

# Get Cloudflare IPv4 and IPv6 ranges:
curl -s https://www.cloudflare.com/ips-v4
curl -s https://www.cloudflare.com/ips-v6

# iptables example โ€” allow Cloudflare IPs on port 443:
while read ip; do
  iptables -I INPUT -s "$ip" -p tcp --dport 443 -j ACCEPT
done < <(curl -s https://www.cloudflare.com/ips-v4)

# UFW example:
ufw allow from 103.21.244.0/22 to any port 443
# (repeat for each Cloudflare CIDR range)

Server bound to wrong interface: If nginx or Apache is configured to listen only on 127.0.0.1 or a private interface, Cloudflare cannot connect. Verify the listen directive:

# nginx โ€” listen on all interfaces:
server {
    listen 0.0.0.0:443 ssl;
    # NOT listen 127.0.0.1:443;
}

# Apache:
Listen 0.0.0.0:443
# NOT Listen 127.0.0.1:443

OOM kill loop: If the web server is being killed by the kernel's OOM killer, add swap space or upgrade server memory. Configure systemd to restart the service on failure:

# /etc/systemd/system/nginx.service.d/override.conf [Service] Restart=always RestartSec=5s

521 vs related Cloudflare errors

CodeTCP resultMeaning
521Connection actively refused (RST)Origin host reachable, no web server process running
522TCP SYN timed outOrigin host unreachable or not responding at all
523Host unreachableDNS resolves but route to host fails
524Connection established, then timed outWeb server started response but never finished
520Connected, response unparseableWeb server running but returning invalid HTTP

Frequently asked questions

How can my server be "up" but still return 521?

The server host (VM, container, bare metal) is up but the web server process is not running. The machine is accepting SSH connections and responding to pings, but nothing is listening on port 80 or 443. Use ss -tlnp to confirm the port is not bound.

Why does 521 happen after a deployment?

Deployments that reload or restart the web server process cause a brief window (typically less than one second) where no process is listening. Cloudflare requests arriving during that window get a refused connection. Use zero-downtime deployment strategies: rolling restarts, blue-green deployments, or nginx's nginx -s reload (which starts new workers before stopping old ones).

Can Cloudflare's "Always Online" feature help during 521?

Yes. Cloudflare Always Online serves cached versions of your pages from Cloudflare's cache when the origin is down. It does not fix the underlying 521, but it maintains partial site availability for cached pages while you resolve the outage.

Does Cloudflare retry 521 requests?

Cloudflare does retry on connection errors for safe (GET, HEAD) requests to multiple origin IPs if you have configured multiple origin IPs or use a load balancer. Single-origin setups with a refused connection will show 521 immediately without retry.

Related guides

Cloudflare 520 ยท Cloudflare 522 ยท Cloudflare 523 ยท Cloudflare 524 ยท HTTP 503 ยท HTTP 502

Server Errors Hub ยท All Guides ยท Home