Connection Timed Out
ActiveHTTP 522 Connection Timed Out is a Cloudflare-specific status indicating Cloudflare could not establish a TCP connection to the origin within 15 seconds. The TCP SYN received no reply at all. Not in any RFC. Common causes: firewall silently dropping packets, server overload, or wrong origin IP.
Description
The 522 Connection Timed Out status code is a Cloudflare-proprietary response indicating that Cloudflare's edge server attempted to establish a TCP connection to the origin server but received no response to its SYN packet within the 15-second timeout window. This is a network-layer failure — the HTTP request was never sent because the underlying TCP handshake never completed.
This is critically different from related Cloudflare errors. A 521 means the origin actively refused the connection (TCP RST received). A 520 means the TCP connection succeeded but the origin returned an invalid or empty HTTP response. A 524 means the TCP connection succeeded AND the HTTP request was sent, but the origin took too long to generate the HTTP response. 522 sits at the earliest point of failure — the three-way handshake never completes because no SYN-ACK comes back.
The most common root causes fall into several categories: the origin server's firewall is configured to DROP (silently discard) rather than REJECT packets from Cloudflare's IP ranges; the origin server is so overloaded that its TCP listen backlog is full and it cannot accept new connections; the origin IP configured in Cloudflare's DNS is wrong (stale A/AAAA record pointing to a decommissioned server); or the network path between Cloudflare's edge and the origin is broken (routing issues, upstream provider outage, DDoS-induced congestion).
Debugging requires verifying connectivity from outside your local network. The origin may respond fine from your office (different network path) while being unreachable from Cloudflare's edge. Key steps: confirm the origin IP is correct, verify the origin firewall explicitly allows Cloudflare's published IP ranges (not just doesn't block them — DROP rules are invisible), check origin server load and connection limits (netstat/ss for SYN_RECV backlog), and test TCP connectivity from an external host using tools like curl, telnet, or mtr.
From the end user's perspective, a 522 presents as a Cloudflare error page stating the host is unreachable. The user cannot resolve this — it requires action from the site operator to restore connectivity between Cloudflare's network and the origin server.
Examples
HTTP/1.1 522 Connection Timed Out
Content-Type: text/html; charset=UTF-8
Server: cloudflare
CF-RAY: 8a1b2c3d4e5f6789-SJC
X-Frame-Options: SAMEORIGIN
<!DOCTYPE html>
<html>
<head><title>api.example.com | 522: Connection timed out</title></head>
<body>
<h1>Connection timed out</h1>
<p>The initial connection between Cloudflare's network and the origin web server timed out. As a result, the web page can not be displayed.</p>
<p>Ray ID: 8a1b2c3d4e5f6789</p>
</body>
</html># Test if origin port 443 is reachable from an external server
$ curl -svo /dev/null --connect-timeout 15 https://203.0.113.50:443
* Trying 203.0.113.50:443...
* Connection timed out after 15001 milliseconds
* Closing connection 0
curl: (28) Connection timed out after 15001 milliseconds
# Trace the network path to identify where packets are dropped
$ mtr --tcp --port 443 203.0.113.50
Host Loss% Snt Last Avg
1. gateway.local 0.0% 10 1.2 1.1
2. isp-router.net 0.0% 10 5.4 5.2
3. upstream-peer.net 0.0% 10 12.1 11.8
4. origin-dc.net 100.0% 10 0.0 0.0 <-- packets dropped here# Check for SYN_RECV overflow (connections waiting for ACK)
$ ss -tnp state syn-recv | wc -l
1024
# Check kernel listen backlog settings
$ sysctl net.core.somaxconn
net.core.somaxconn = 128 # Too low for high traffic
# Check current connection count on port 443
$ ss -tn state established '( dport = :443 or sport = :443 )' | wc -l
4892
# Check for SYN flood protection dropping legitimate connections
$ dmesg | grep "SYN flooding"
[1842395.123] TCP: request_sock_TCP: Possible SYN flooding on port 443. Sending cookies.# Query Cloudflare's health check for the origin
$ curl -s -X GET "https://api.cloudflare.com/client/v4/zones/ZONE_ID/origin_health" \
-H "Authorization: Bearer CF_API_TOKEN" \
-H "Content-Type: application/json" | jq '.result'
{
"origin_ip": "203.0.113.50",
"healthy": false,
"failure_reason": "tcp_timeout",
"last_checked": "2024-03-15T14:22:00Z",
"last_healthy": "2024-03-15T13:45:00Z",
"consecutive_failures": 12
}# Download current Cloudflare IPv4 ranges
$ curl -s https://www.cloudflare.com/ips-v4 > /tmp/cf-ips-v4.txt
# Add ACCEPT rules for all Cloudflare IPs (BEFORE any DROP rules)
$ while read ip; do
iptables -I INPUT -s "$ip" -p tcp --dport 443 -j ACCEPT
iptables -I INPUT -s "$ip" -p tcp --dport 80 -j ACCEPT
done < /tmp/cf-ips-v4.txt
# Verify Cloudflare IPs are not hitting a DROP rule
$ iptables -L INPUT -n --line-numbers | grep -E "DROP|REJECT"
15 DROP tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443
# ^ If this rule is BEFORE the Cloudflare ACCEPT rules, connections will timeout# /etc/nginx/nginx.conf — tune for Cloudflare traffic volume
events {
worker_connections 4096; # Default 768 is too low
multi_accept on;
}
http {
# Increase keepalive to reduce new TCP connections
keepalive_timeout 65;
keepalive_requests 1000;
# Allow only Cloudflare IPs to connect (defense in depth)
# This also confirms the right IPs are whitelisted
allow 173.245.48.0/20;
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 141.101.64.0/18;
allow 108.162.192.0/18;
allow 190.93.240.0/20;
allow 188.114.96.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;
allow 162.158.0.0/15;
allow 104.16.0.0/13;
allow 104.24.0.0/14;
allow 172.64.0.0/13;
allow 131.0.72.0/22;
deny all;
}Edge Cases
- •A 522 does NOT mean the origin is down — it means Cloudflare specifically cannot reach it. The origin may be perfectly accessible from other networks (firewall rules targeting Cloudflare IPs, geo-blocking, or asymmetric routing).
- •Cloudflare's 15-second TCP timeout is not configurable by the site operator. If your origin consistently takes >10s to accept TCP connections, the architecture needs to change (closer origin, lower load, connection pooling).
- •If Cloudflare recently onboarded a new edge location, its IP range may not be in your origin firewall allowlist yet. Always pull from the live Cloudflare IP list rather than hardcoding ranges.
- •Origin servers behind a load balancer may show 522 intermittently if one backend node is unhealthy — the LB routes some connections to the dead node. Health checks at the LB layer must detect TCP-level unresponsiveness.
- •During a DDoS attack on the origin (bypassing Cloudflare via leaked origin IP), the origin's connection table may fill up, causing legitimate Cloudflare connections to timeout with 522 even though the origin is technically running.
- •A kernel-level SYN flood protection (syncookies) that is misconfigured can silently drop connections from Cloudflare that exceed rate limits, producing 522s with no log entries on the origin.
- •MTU path issues between Cloudflare and origin can cause TCP SYN packets to be fragmented and dropped by intermediate routers, appearing as a 522 with no obvious firewall or server issue.
When You'll See This
- →Origin server firewall silently DROPs packets from Cloudflare IP ranges instead of ACCEPTing them
- →Origin server is overloaded — TCP listen backlog full, new SYN packets are discarded by the kernel
- →DNS misconfiguration — Cloudflare A record points to a decommissioned or incorrect origin IP
- →Network path outage between Cloudflare edge POP and the origin datacenter (upstream transit failure)
- →Origin server migrated to a new IP but Cloudflare DNS was not updated
- →Hosting provider rate-limiting inbound connections — Cloudflare's volume triggers the limit
- →Origin behind a cloud security group that doesn't include Cloudflare's full IP range
- →DDoS attack on origin (via leaked IP) fills the connection table, preventing Cloudflare connections
Implementation References
| Language | Constant |
|---|---|
| Cloudflare Workers | 522 (not programmable — edge-generated before worker executes) |
| Go | 522 (no standard constant — use raw integer) |
| Node.js | 522 (not in http.STATUS_CODES — Cloudflare proprietary) |
| Python (requests) | response.status_code == 522 (recognized but unnamed) |
| Nginx | Not applicable (Nginx is typically the origin, not the reporter) |
| HAProxy | Not applicable (only Cloudflare's edge generates 522) |
| curl | Received as HTTP status 522 in response line |
| Cloudflare API | Reported in analytics as 'origin_connection_timeout' |
History
Introduced by Cloudflare around 2010 as part of their proprietary error code range (520-527) for reverse proxy edge cases that standard HTTP status codes don't cover. The 5xx range was chosen because from the client's perspective, the failure is server-side — but Cloudflare categorizes these as 'unofficial' since they are not registered with IANA or defined in any RFC. The 522 specifically addresses the TCP timeout scenario that is unique to split-connection architectures where the CDN terminates the client's TCP connection and must open a separate connection to the origin. As Cloudflare grew to proxy over 20% of web traffic, these proprietary codes became de facto standards that every web developer encounters.
Related Status Codes
Related Headers
FAQ
What is the difference between 522 Connection Timed Out and 524 A Timeout Occurred?
522 and 524 represent failures at fundamentally different layers. 522 means the TCP three-way handshake never completed — Cloudflare sent a SYN packet and got no SYN-ACK back within 15 seconds. The HTTP request was never transmitted. 524 means the TCP connection was established successfully (SYN-ACK received, handshake complete) and the HTTP request was sent, but the origin took too long to send back an HTTP response (default 100 seconds for Enterprise, 60 seconds for other plans). In short: 522 = network/transport layer failure (can't connect), 524 = application layer failure (connected but origin is slow to respond). Fix 522 by checking firewalls and network reachability. Fix 524 by optimizing origin response time or increasing Cloudflare's proxy read timeout.
How do I fix a 522 error on my Cloudflare-proxied site?
Systematic debugging approach: (1) Verify the origin IP in Cloudflare DNS is correct — check your A/AAAA records match the actual server. (2) From an external server (not your local machine), test TCP connectivity: 'curl -svo /dev/null --connect-timeout 15 https://YOUR_ORIGIN_IP'. If this times out, the issue is confirmed. (3) Check your origin firewall — the most common cause is a DROP rule catching Cloudflare IPs. Download https://www.cloudflare.com/ips-v4 and ensure every range has an explicit ACCEPT rule positioned BEFORE any broad DROP rules. (4) Check origin server load: 'ss -s' shows connection statistics; if SYN-RECV count is high, increase net.core.somaxconn and your web server's backlog. (5) Check with your hosting provider — some providers rate-limit inbound connections or have their own firewall layer you can't see. (6) If intermittent, check if a load balancer is routing some traffic to an unhealthy backend node.
Why does my origin work fine when I access it directly but Cloudflare gets 522?
This almost always means a firewall or network path issue specific to Cloudflare's IP ranges. When you access the origin directly, you're using your ISP's IP from your geographic location — a completely different source IP and network path than Cloudflare uses. Common causes: (1) Your origin firewall has a default DROP policy and only allows known IPs — Cloudflare's ranges aren't in the allowlist. (2) Your hosting provider's network firewall (above your server's iptables) blocks Cloudflare IPs. (3) A geo-IP blocking rule is catching Cloudflare edge IPs that come from data centers in countries you've blocked. (4) Rate limiting rules trigger because Cloudflare concentrates many users' requests through a smaller set of IPs. (5) Asymmetric routing — packets from Cloudflare take a different path that hits a broken intermediate router. Test from a VPS in a different datacenter to confirm the origin is reachable from outside your local network.