Quick Triage Matrix
Cloudflare 5xx Error Comparison at a Glance
Each error represents a breakdown at a specific layer of the network stack between Cloudflare's edge proxy and your origin server:
| Error Code | Official Status Name | Failure Layer | Underlying Root Cause | Immediate Sysadmin Triage |
|---|---|---|---|---|
| 520 | Web Server Returns an Unknown Error | HTTP Response Stream | Origin server closed TCP abruptly, sent empty payload, or headers exceeded 16 KB. | Inspect origin crash logs (PHP-FPM, Apache segfault); verify response header size. |
| 521 | Web Server Is Down | TCP SYN / Port Listening | Origin web server refused TCP connection; responded with TCP RST on port 80/443. | Verify daemon is running (systemctl status nginx) and bound to 0.0.0.0. |
| 522 | Connection Timed Out | TCP 3-Way Handshake | TCP SYN dropped by firewall (iptables/UFW/AWS SG); no SYN-ACK within 15s. | Ensure all Cloudflare IP ranges are allowlisted in origin firewall and security groups. |
| 524 | A Timeout Occurred | HTTP Request Execution | TCP handshake succeeded, but origin produced no HTTP response within 100 seconds. | Identify long-running database queries, slow API calls, or worker pool starvation. |
| 502 | Bad Gateway | Upstream Gateway / FastCGI | Origin reverse proxy (NGINX) received invalid or empty response from upstream app socket. | Check PHP-FPM / Node / Python socket availability and NGINX error.log. |
Architecture & Topology
The 4-Tier Packet Flow: Where Connections Drop
To quickly troubleshoot 5xx outages, you must understand which network hop broke down. Cloudflare operates as a reverse proxy sitting between visitor web browsers and your origin infrastructure:
Client Browser
User Agent (Chrome, Safari, cURL, Mobile App)
Cloudflare Edge
Anycast POPs, WAF, CDN Cache, DDoS Shield
Origin Server
Firewall (iptables/UFW), NGINX/Apache Reverse Proxy
Upstream App
PHP-FPM, Node.js, Python WSGI, PostgreSQL
[Client Browser]
│
▼ HTTPS (TCP 443 / TLS 1.3)
[Cloudflare Edge Anycast POP]
│
├─── [TCP SYN] ───────────────────► [Origin Firewall / iptables]
│ │
│ DROPPED by iptables/UFW
│ ▼
│ ◄─── (No SYN-ACK after 15s) ──────── ❌ ERROR 522 Connection Timed Out
│
├─── [TCP SYN] ───────────────────► [Origin Port 80/443]
│ │
│ NO DAEMON LISTENING
│ ▼
│ ◄─── [TCP RST / Connection Refused] ❌ ERROR 521 Web Server Is Down
│
├─── [HTTP GET] ──────────────────► [Origin NGINX Web Server]
│ │
│ EXECUTES BACKEND SCRIPT
│ ▼
│ [PHP-FPM / Node / Database]
│ │
│ Hangs > 100 seconds
│ ▼
│ ◄─── (Edge Gateway Timeout) ──────── ❌ ERROR 524 A Timeout Occurred
│
├─── [HTTP GET] ──────────────────► [Origin Web Server]
│ │
│ EMITS EMPTY / CORRUPT DATA
│ ▼
│ ◄─── [TCP Reset Mid-Stream / >16KB] ─ ❌ ERROR 520 Web Server Returns Unknown
│
└─── [HTTP GET] ──────────────────► [Origin NGINX]
│
Proxy pass to unix socket
▼
[Upstream App CRASHED]
▼
❌ ERROR 502 Bad GatewayTechnical Breakdown
Granular Analysis by Cloudflare Status Code
Error 520: Web Server Returns an Unknown Error
Error 520 occurs when Cloudflare successfully establishes a TCP connection and dispatches the HTTP request, but the origin web server returns something unexpected, unparseable, or completely empty.
Wire-level conditions that trigger 520:
- TCP Reset Mid-Stream: The origin server abruptly terminates the TCP connection with a TCP RST packet before completing the HTTP header transmission. This frequently occurs when an Apache or NGINX child worker processes segfaults or runs out of RAM.
- Empty HTTP Response: The origin accepts the connection and immediately sends a 0-byte response followed by a TCP FIN.
- Header Size Exceeded: Cloudflare imposes a strict 16 KB limit on individual HTTP response headers and a 32 KB limit on total headers. Excessive Set-Cookie payloads or debug headers trigger an immediate 520.
- Invalid Chunked Encoding: The origin specifies
Transfer-Encoding: chunkedbut transmits malformed chunk lengths or terminates early.
Error 521: Web Server Is Down
Error 521 indicates that Cloudflare sent a TCP SYN packet to your origin server's public IP address on port 80 or 443, and your origin server actively replied with a TCP RST (Reset) packet, refusing the connection.
Primary causes of connection refusal:
- Web Daemon Stopped or Crashed: NGINX, Apache, Caddy, or IIS is not running. Memory exhaustion (Linux OOM-killer) frequently terminates web server daemons under traffic surges.
- Localhost Binding Misconfiguration: The web server is configured to listen on
127.0.0.1:443instead of the public network interface or wildcard0.0.0.0:443. - Port Mismatch: Cloudflare's SSL/TLS mode is set to "Full" or "Full (Strict)", but the origin server does not have an SSL certificate installed or is not listening on port 443.
sudo ss -tulpn | grep -E ':(80|443)'
Error 522: Connection Timed Out
Unlike 521 where the server actively refuses the connection, Error 522 means Cloudflare received no response at all. Cloudflare sent a TCP SYN packet to complete the 3-way handshake, but timed out after 15 seconds without receiving a SYN-ACK.
Primary causes of handshake timeouts:
- Firewall IP Blocking / Rate Limiting: Origin firewalls (such as iptables, UFW, Fail2ban, CSF, or AWS Security Groups) observe heavy traffic from Cloudflare IPs and mistakenly trigger automated IP ban rules, dropping TCP SYN packets.
- Network Routing Blackholes: Routing issues between Cloudflare's transit providers and your hosting facility's upstream network drops packets en route.
- Backlog Queue Full: The origin server's TCP listen backlog (
net.core.somaxconn) is completely saturated, causing the Linux kernel to drop incoming SYN packets.
sudo iptables -L INPUT -v -n | grep DROP
# Ensure all ranges from https://www.cloudflare.com/ips/ are ACCEPTED
Error 524: A Timeout Occurred
Error 524 occurs when Cloudflare successfully establishes a TCP connection and delivers the HTTP request to the origin, but the origin web server fails to send any HTTP response headers back within Cloudflare's default 100-second timeout.
Common engineering causes of 524:
- Long-Running Database Queries: Heavy data exports, table scans, or unindexed JOIN operations holding synchronous HTTP worker threads.
- PHP-FPM Worker Starvation: All available PHP-FPM children (
pm.max_children) are occupied, placing incoming requests in an indefinite queue. - Synchronous File Processing: Uploading, compressing, or watermarking large media files directly inside the web request lifecycle instead of delegating to asynchronous queues (e.g., Redis, Celery, BullMQ).
Error 502: Bad Gateway (Origin vs Cloudflare)
Under RFC 9110 §15.6.3, a 502 Bad Gateway indicates that a server acting as a gateway or proxy received an invalid response from an inbound server. In Cloudflare setups, 502s fall into two distinct categories:
Cloudflare was able to connect to the origin, but the origin returned an invalid or completely empty response, or an unexpected TLS handshake failure occurred during origin negotiation.
The origin web server (NGINX) is running, but its internal reverse proxy connection to PHP-FPM, Node.js, or Gunicorn failed (connect() to unix:/var/run/php/php-fpm.sock failed: Connection refused).
Interactive Decision Tree
Step-by-Step Sysadmin Triage Checklist
Follow this sequential procedure whenever a Cloudflare 5xx outage strikes production:
- Step 1: Inspect the Error Footer for Ray ID & Location
At the bottom of the Cloudflare 5xx error screen, note the Cloudflare Ray ID (e.g.,
Ray ID: 87b4c910fae12345) and the 3-letter IATA airport code (e.g.,IAD,LHR). This identifies the exact edge datacenter that handled the request. Cross-reference this Ray ID in your origin NGINX or Apache access logs to confirm whether the request ever reached your server. - Step 2: Bypass Cloudflare Using Direct cURL to Origin IP
Run this command from your local terminal to isolate the origin from Cloudflare:
curl -svo /dev/null -H "Host: yourdomain.com" https://ORIGIN_SERVER_IP/• If this returns HTTP 200 OK, your origin server is operational; the problem is likely an origin firewall blocking Cloudflare IPs (522) or SSL certificate mismatch.
• If this returns Connection refused, your web server is stopped (521).
• If this times out, your server network interface is down or dropping traffic. - Step 3: Check System Resource Saturation
SSH into the origin server and inspect CPU, RAM, and load averages:
uptime && free -m && dmesg -T | grep -i oomIf the Linux kernel's Out-Of-Memory (OOM) killer recently terminated PHP-FPM, MySQL, or NGINX processes, you will see kernel kill events in
dmesg. - Step 4: Verify Origin Firewall Allowlist
Ensure your hosting provider security groups, AWS VPC Network ACLs, and host-level firewalls allow incoming traffic on ports 80 and 443 from all official Cloudflare IP blocks:
curl -s https://www.cloudflare.com/ips-v4 && curl -s https://www.cloudflare.com/ips-v6
Frequently Asked Questions
Cloudflare 5xx Triage FAQs
What is the fundamental difference between Cloudflare 522 and 524 errors?
The critical distinction lies in where the TCP connection fails. A Cloudflare 522 (Connection Timed Out) error occurs during the initial TCP 3-way handshake: Cloudflare's edge node sends a TCP SYN packet to your origin server's IP address on port 80 or 443, but receives no SYN-ACK response within 15 seconds because an origin firewall (like iptables or AWS Security Group) silently dropped the packet. In contrast, a 524 (A Timeout Occurred) error means the TCP handshake succeeded and Cloudflare successfully dispatched the HTTP request, but the origin server failed to return any HTTP response headers within Cloudflare's 100-second execution window (often due to an unindexed SQL query or hanging background worker).
Why does Cloudflare return Error 520 instead of a standard HTTP 500 or 502?
Cloudflare synthesizes Error 520 ('Web Server Returns an Unknown Error') as a catch-all when the origin server behaves in a non-RFC-compliant manner that Cloudflare cannot parse as valid HTTP. This happens when the origin web server closes the TCP connection abruptly (TCP RST) while transmitting headers, returns a completely blank response (0 bytes), exceeds Cloudflare's 16 KB individual header size limit, or emits an invalid HTTP response string (such as protocol version mismatches). Because the origin did not return a valid HTTP 500 or 502 status payload, Cloudflare generates the 520 error at its edge.
How can I verify whether an error is coming from Cloudflare or my origin server?
Look at the error page branding and HTTP response headers. Cloudflare-generated errors display the Cloudflare logo, a distinctive 3-tier diagram showing your browser, Cloudflare, and the origin server with an X on the failed leg, and a Cloudflare Ray ID footer. Origin-generated errors typically return bare NGINX or Apache default 502/500 error pages. You can also inspect the 'Server' header using browser DevTools or cURL: a Cloudflare edge error returns 'Server: cloudflare' and 'cf-ray', while an origin 502 will pass through the origin's custom response body if Cloudflare successfully proxied the origin's explicit 502 response.
How do I bypass Cloudflare using cURL to test my origin server directly?
Use cURL's '--resolve' flag or an explicit Host header to send the request directly to your origin web server's public IP address, bypassing Cloudflare's Anycast network: 'curl -svo /dev/null -H "Host: yourdomain.com" https://ORIGIN_SERVER_IP/'. Alternatively, use: 'curl -svo /dev/null --resolve yourdomain.com:443:ORIGIN_SERVER_IP https://yourdomain.com/'. If this cURL command returns HTTP 200 OK with your application payload, the failure is occurring inside the Cloudflare-to-origin transit layer (such as firewall rate-limiting). If it fails or times out, the defect is entirely on your origin web server.
Why does my origin server firewall block Cloudflare IPs causing 522 errors?
When a website sits behind Cloudflare's reverse proxy, thousands of unique visitor requests arrive at the origin server multiplexed through a relatively small pool of Cloudflare Anycast IP addresses. Origin-side security daemons like Fail2ban, CSF (ConfigServer Security & Firewall), UFW, or cloud provider Web Application Firewalls often perceive this high-volume stream as an HTTP flood or brute-force attack and automatically inject iptables DROP rules against Cloudflare's IP subnets. To permanently resolve this, sysadmins must explicitly allowlist Cloudflare's published IPv4 and IPv6 CIDR blocks in their origin firewall rules.
Authority Citations
Verified Primary Sources & Standards
The diagnostic classifications, packet flow boundaries, and status code semantics in this guide are directly derived from official IETF RFC standards and Cloudflare technical documentation:
Official IETF normative specification for HTTP 5xx Server Error status codes (§15.6) including 500, 502, 503, and 504.
View IETF RFC 9110 Cloudflare 5xx Troubleshooting DocumentationOfficial Cloudflare developer troubleshooting documentation for error codes 520, 521, 522, 523, 524, 525, and 526.
Cloudflare 5xx Docs