cf-custom-codes

Cloudflare Custom Codes

The full 520–527 range, each with what actually happened, whose knob it is, and the honest blame assignment the error page won’t give you:

520: “Web server returns an unknown error.”

The garbage drawer. CF got something it couldn’t parse as HTTP: connection reset mid-response, empty reply, malformed headers, headers over CF’s ~32KB limit (classic: apps echoing huge cookies), or origin closing the socket. Blame: genuinely origin-side usually, but it’s a catch-all by construction, so it also swallows MTU/middlebox weirdness on the path. The worst-designed of the eight — it’s “something broke, we refuse to say what,” and a decade of forum archaeology exists because the diagnostic detail lives only in CF’s internal logs (Enterprise customers can see it; everyone else guesses). An RFC 9457 problem-details body would have deleted thousands of support threads.

521:“Web server is down.”

TCP connection refused — origin actively rejected the SYN. Blame: origin-side, honestly earned… except the number-one real-world cause is the origin’s firewall blocking Cloudflare’s published IP ranges, i.e., a config interaction where the origin admin didn’t allowlist CF. Still origin-knob, but “down” is a lie; the server’s up and refusing them.

522: “Connection timed out.”

SYN sent, no completion within CF’s timeout (~15s to connect); or origin accepted but CF’s overall origin-pull window expired. Blame: split. Origin overload/slow accept queue is origin-side; but drops of CF’s IPs by rate-limiters, or asymmetric routing eating the path, land here too. The diagram blames the host for what is frequently a path or filtering problem.

523 “Origin is unreachable.”

No route: DNS for the origin (in CF’s config) resolves to nothing usable, or the network path is gone entirely — commonest with Argo Tunnel/cloudflared setups where the tunnel died, or a stale origin IP after a migration. Blame: config-side about half the time (stale CF-side origin records), infra-side the rest. Again “origin” in the name, dashboard knob in reality.

524 “A timeout occurred.”

The interesting one: TCP + TLS succeeded, HTTP request sent, origin didn’t return headers within 100 seconds (Enterprise can raise it; everyone else can’t). Blame: origin-side in the sense that your app is slow, but it’s really an architectural error — CF is telling you synchronous request/response has a hard 100s ceiling on their edge and your long-running report generator needs to be async. Notable as the only 52x that’s a documented, intentional product limit rather than a failure.

525 “SSL handshake failed.”

Covered last message: CF dialed 443 per your SSL mode, handshake died (nothing listening on 443, no SNI, cipher mismatch). Blame: contract mismatch, knob is CF-side (mode) or origin-side (serve TLS), and the page picks the wrong column.

526 “Invalid SSL certificate.”

Handshake completed, cert failed Full (strict) validation — expired, self-signed, wrong hostname, untrusted chain. Blame: the strictness is your CF-side election; whether the right fix is “fix the origin cert” or “you never issued one and strict is deadlocking your ACME flow” is exactly the ambiguity from earlier. Only meaningful under strict; the same origin under plain Full sails through.

527 “Railgun error.”

Historical curiosity: failure in the Railgun WAN-optimization protocol between CF and an origin-side Railgun listener. Railgun was deprecated and killed (~2023–24), so 527 is a dead code — but it’s instructive as the purest case of the naming problem: an error in Cloudflare’s own proprietary appliance still got filed in the “origin problem” namespace.

See Also

Further Reading

 

rtfrfc

read the fine rfc


By [eliferrous], 2026-07-24