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 CodeOfficial Status NameFailure LayerUnderlying Root CauseImmediate Sysadmin Triage
520Web Server Returns an Unknown ErrorHTTP Response StreamOrigin server closed TCP abruptly, sent empty payload, or headers exceeded 16 KB.Inspect origin crash logs (PHP-FPM, Apache segfault); verify response header size.
521Web Server Is DownTCP SYN / Port ListeningOrigin 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.
522Connection Timed OutTCP 3-Way HandshakeTCP 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.
524A Timeout OccurredHTTP Request ExecutionTCP handshake succeeded, but origin produced no HTTP response within 100 seconds.Identify long-running database queries, slow API calls, or worker pool starvation.
502Bad GatewayUpstream Gateway / FastCGIOrigin 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:

NETWORK TOPOLOGY: Cloudflare Edge to Origin BackendHop-by-Hop Breakdown
TIER 1

Client Browser

User Agent (Chrome, Safari, cURL, Mobile App)

TLS 1.3 / HTTP/2 or HTTP/3
✓ Client → Cloudflare OK
TIER 2

Cloudflare Edge

Anycast POPs, WAF, CDN Cache, DDoS Shield

Generates 5xx when:
• SYN Refused: 521
• Handshake Timeout: 522
• 100s Limit Exceeded: 524
• Corrupt Header: 520
TIER 3

Origin Server

Firewall (iptables/UFW), NGINX/Apache Reverse Proxy

Listens on 80/443
Firewall Drops → 522
Service Down → 521
TIER 4

Upstream App

PHP-FPM, Node.js, Python WSGI, PostgreSQL

FastCGI / Unix Socket
Socket Crash → 502
>100s Query → 524
[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 Gateway

Technical Breakdown

Granular Analysis by Cloudflare Status Code

Status 520 · HTTP Response StreamMalformed Response

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: chunked but transmits malformed chunk lengths or terminates early.
Sysadmin Verification Command:
curl -svo /dev/null -H "Host: example.com" https://ORIGIN_IP/ 2>&1 | grep -E "(Connected|HTTP\/|Closing connection)"
Status 521 · Port Connection RefusedService Down

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:443 instead of the public network interface or wildcard 0.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.
Sysadmin Verification Commands:
sudo systemctl status nginx
sudo ss -tulpn | grep -E ':(80|443)'
Status 522 · TCP Handshake TimeoutPacket Dropped

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.
Sysadmin Remediation: Allowlist Cloudflare IP Prefixes
# Check active iptables DROP rules
sudo iptables -L INPUT -v -n | grep DROP
# Ensure all ranges from https://www.cloudflare.com/ips/ are ACCEPTED
Status 524 · 100-Second Gateway LimitExecution Timeout

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).
Architectural Fix:
Offload long tasks to background workers and return HTTP 202 Accepted with a job status polling URL.
Status 502 · RFC 9110 Bad GatewayUpstream Crash

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 Edge 502

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.

Origin Internal 502

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).

Check NGINX Error Log for Upstream Socket Failures:
sudo tail -n 50 /var/log/nginx/error.log | grep -E "(connect\(\) failed|upstream prematurely closed)"

Interactive Decision Tree

Step-by-Step Sysadmin Triage Checklist

Follow this sequential procedure whenever a Cloudflare 5xx outage strikes production:

  1. 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.

  2. 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.

  3. 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 oom

    If 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.

  4. 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:

Related HTTP & Diagnostic Resources