Skip to main content
520

Web Server Returned an Unknown Error

Active
None (Cloudflare proprietary) N/ASince 2010Cloudflare-proxied origins, CDN edge networks, reverse proxy configurations

HTTP 520 is a Cloudflare-specific status code indicating the origin server returned an unexpected, empty, or malformed response that Cloudflare cannot interpret. Not defined in any RFC. It's a catch-all for broken communication between Cloudflare's edge and your origin. Debug by bypassing Cloudflare and hitting the origin directly.

Description

The 520 status code is a proprietary Cloudflare error indicating that the origin server returned something Cloudflare's edge proxy cannot parse or process. Cloudflare generates this code itself — the origin never sends a 520. When you see this error page (always Cloudflare-branded), it means the connection between Cloudflare and your origin broke in a way that doesn't fit any other specific error category.

Common triggers include: the origin returned an empty response body with no headers, the origin closed the TCP connection before sending a complete HTTP response, the response headers exceeded Cloudflare's buffer limits (typically 32KB for headers), the origin sent a malformed or incomplete HTTP response, or the origin returned a non-standard response that violated HTTP protocol expectations. Essentially, anything that isn't a clean HTTP response triggers a 520.

The 520 is Cloudflare's catch-all. Their other 5xx-range codes (521–527) cover specific failure modes — origin down, connection timeout, unreachable, SSL failures. If none of those match but something is still wrong, it becomes a 520. Think of it as the 'else' clause in Cloudflare's error classification logic.

Debugging requires bypassing Cloudflare entirely. Point your request directly at the origin IP, or check origin server logs for what it actually sent back. Common culprits: crashed application processes returning empty responses, reverse proxy misconfigurations (nginx/Apache sending incomplete headers), firewall rules dropping connections mid-response, and application timeouts that close sockets without sending proper HTTP responses.

This code has no standards body behind it — it exists purely in Cloudflare's documentation. Other CDN providers may have equivalent proprietary codes, but 520 specifically means Cloudflare is in your request path and something between their edge and your origin failed in an unclassifiable way.

Examples

Request to a Cloudflare-proxied domain
http
GET /api/users HTTP/1.1
Host: api.example.com
Accept: application/json
CF-Connecting-IP: 203.0.113.50
520 response — Cloudflare cannot interpret origin response
http
HTTP/1.1 520 
Content-Type: text/html; charset=UTF-8
Server: cloudflare
CF-RAY: 7a1b2c3d4e5f6g7h-SJC
X-Frame-Options: SAMEORIGIN

<!DOCTYPE html>
<html>
<head><title>Web server is returning an unknown error</title></head>
<body>
  <h1>Error 520</h1>
  <p>Web server is returning an unknown error</p>
  <p>Cloudflare Ray ID: 7a1b2c3d4e5f6g7h</p>
</body>
</html>
Bypassing Cloudflare — direct origin request for debugging
shell
# Find origin IP (from DNS history or server config)
# Hit it directly, bypassing Cloudflare
curl -v --resolve api.example.com:443:93.184.216.34 \
  https://api.example.com/api/users

# Check what the origin actually returns
# If you get empty response or connection reset — that's your 520 cause
Origin returning empty response (causes 520)
shell
# Simulating what an origin might do wrong:
# Empty response — no headers, no body
$ nc -l 8080 <<< ""

# Connection reset mid-response
$ curl -v http://origin:8080/health
* Connected to origin (127.0.0.1) port 8080
* Empty reply from server
* Closing connection
curl: (52) Empty reply from server
Checking Cloudflare headers for debugging info
http
HTTP/1.1 520 
Server: cloudflare
CF-RAY: 7a1b2c3d4e5f6g7h-SJC
CF-Cache-Status: DYNAMIC
X-Request-ID: req_abc123
Retry-After: 30

# Key debugging headers:
# CF-RAY — unique request ID, use in Cloudflare dashboard logs
# CF-Cache-Status: DYNAMIC — confirms this hit the origin
# The Ray ID tells you which Cloudflare data center handled it
nginx misconfiguration causing 520 (oversized headers)
# nginx.conf — proxy_buffer_size too small for response headers
server {
    location / {
        proxy_pass http://app:3000;
        proxy_buffer_size 4k;        # Too small!
        proxy_buffers 8 4k;          # App sends 40KB of Set-Cookie headers
    }
}

# Result: nginx sends partial/malformed response to Cloudflare
# Cloudflare can't parse it → 520

# Fix:
proxy_buffer_size 128k;
proxy_buffers 8 128k;

Edge Cases

  • 520 is generated BY Cloudflare, never by the origin. If your origin logs show no request at all, Cloudflare may have failed to connect (check 521/522 instead) — 520 means it connected but got garbage back.
  • An origin returning a valid HTTP response with unusual but legal headers will NOT trigger 520. The response must be genuinely malformed, empty, or violate HTTP framing.
  • Intermittent 520s often indicate application crashes — the process dies mid-response. Check for OOM kills, segfaults, or unhandled exceptions that terminate the process before flushing the response.
  • Load balancers between Cloudflare and your origin can CAUSE 520s. If the LB returns its own error page in a format Cloudflare doesn't expect, or if it drops the connection during failover, Cloudflare sees a broken response.
  • Cloudflare has a 100-second default timeout for origin responses. If your origin takes longer than this WITHOUT sending any bytes, you'll get a 524 (timeout). If it starts sending bytes but then stops mid-response, you may get a 520 instead.
  • Large Set-Cookie headers or excessive response headers (over ~32KB total) can trigger 520 because Cloudflare's header buffer overflows before it can process the response.
  • Keep-alive connection reuse can cause spurious 520s. If the origin closes a keep-alive connection just as Cloudflare tries to reuse it, Cloudflare reads an empty response from a dead socket.

When You'll See This

  • Origin application crashes mid-response (process killed by OOM, unhandled exception terminates worker)
  • Origin returns empty response — connected successfully but sent zero bytes before closing
  • Response headers exceed Cloudflare's buffer limit (~32KB) due to excessive cookies or custom headers
  • Origin's reverse proxy (nginx/Apache) sends malformed HTTP response due to misconfiguration
  • Firewall or WAF between Cloudflare and origin drops the connection after partial response
  • Keep-alive socket reuse race condition — origin closed connection just as Cloudflare sent the next request
  • Origin sends HTTP/2 response when Cloudflare expects HTTP/1.1 on the backend connection
  • Application sends chunked transfer encoding but terminates the stream incorrectly (missing final 0-length chunk)

Implementation References

LanguageConstant
Cloudflare Workers520 (not exposed — Workers run on the edge, before this error is generated)
Go520 (no stdlib constant — use raw int)
Python (requests)response.status_code == 520 (no named constant)
Node.js520 (not in http.STATUS_CODES — non-standard)
cURLcurl returns HTTP code 520 in -w '%{http_code}'
nginxUsed as custom error code in proxy_intercept_errors
HAProxyCustom http-response status 520 in error handling
Terraform (Cloudflare)cloudflare_page_rule with status code routing for 520

History

Introduced around 2010 as part of Cloudflare's proprietary error code range (520–527). These codes exist because Cloudflare sits between clients and origins, creating failure modes that standard HTTP codes don't cover. The standard 502 Bad Gateway was insufficient — it doesn't distinguish between 'origin is completely down' (521), 'connection timed out' (522), 'origin unreachable' (523), and 'got something back but couldn't understand it' (520). As Cloudflare grew to proxy over 20% of web traffic, these codes became de facto standards that developers worldwide learned to debug, despite having no IETF backing. The 520 specifically has remained the 'unknown/catch-all' bucket throughout its history — a sign that origin-edge communication fails in endlessly creative ways.

Related Status Codes

Related Headers

FAQ

What causes a 520 error and how do I fix it?

A 520 means Cloudflare connected to your origin server but received a response it couldn't interpret — empty body, malformed headers, connection closed mid-response, or protocol violations. To fix: (1) Check origin server logs for crashes, OOM kills, or unhandled exceptions at the time of the error. (2) Bypass Cloudflare by hitting the origin IP directly with curl -v to see what it actually returns. (3) Check for oversized response headers (Cloudflare buffers ~32KB). (4) Ensure your reverse proxy (nginx/Apache) is correctly configured for proxy_buffer_size and proxy_pass. (5) Look for firewall rules or security groups that might be dropping connections. The CF-RAY header in the error response helps correlate with Cloudflare's dashboard logs.

Is 520 a standard HTTP status code?

No. 520 is entirely proprietary to Cloudflare. It does not appear in any RFC, is not registered with IANA, and is not recognized by standard HTTP libraries (you won't find http.STATUS_CODES[520] in Node.js or an equivalent constant in Go/Python/Java). The entire 520-527 range is Cloudflare's custom error space for edge-to-origin communication failures. Other CDN providers (AWS CloudFront, Fastly, Akamai) have their own mechanisms for similar failures but don't use these codes. If you see a 520, Cloudflare is definitively in your request path.

How is 520 different from 502 Bad Gateway?

502 Bad Gateway is a standard HTTP code (RFC 9110) meaning the gateway received an invalid response from the upstream server. 520 is Cloudflare's more specific version — it means the response was not just invalid but unparseable: empty, incomplete, or protocol-violating. In practice: 502 might mean the origin returned a valid HTTP response with an error status that the proxy considers invalid. 520 means the origin returned something that isn't even recognizable as HTTP — raw bytes, empty socket, partial headers, or violated framing. Cloudflare uses 502 for its own errors and reserves 520 for 'the origin gave us something we literally cannot process.'