Migrate to RunxBuild and earn up to $50 in hosting credit on your first deposit.

Calculate your savings
unxBuild
Back to Blog Troubleshooting

Error 520: When the Origin Returns Something the Proxy Cannot Understand

Sean

Platform Writer

Sep 01, 2026
8 min read

Error 520 is the proxy saying it received something from your origin that was not a valid HTTP response: an empty reply, a malformed one, or a connection closed mid-answer.

Error 520: When the Origin Returns Something the Proxy Cannot Understand

It is the vaguest error in the 5xx family precisely because it is a catch-all. The proxy connected successfully, sent a request, and got back something it could not parse into a response, so it has nothing more specific to tell you.

That vagueness is why it feels harder to debug than a 522 or a 504. But the underlying causes are a short and knowable list, and the diagnostic that separates them is always the same: bypass the proxy and look at the raw bytes your origin actually sends.

Table of contents

What the proxy actually saw

A valid HTTP response needs a status line, headers, and a body consistent with those headers. A 520 means one of those was missing or wrong.

The realistic forms this takes:

  • An empty response. The connection was accepted and closed with no bytes sent, which is what a crashed worker looks like from outside.
  • A response with no status line, or a garbled one.
  • Headers exceeding the proxy’s size limits, which large session cookies or long authentication headers can do.
  • A connection closed part-way through the body, so the content length promised does not match what arrived.
  • A protocol mismatch, where the origin advertised HTTP/2 support and then did not speak it correctly.

Notice the pattern: in every case the origin did respond, which is what separates this from a 522 where nothing came back at all. Your access log will usually contain the request, which is a helpful difference. Whether the status recorded there matches what the proxy saw is itself informative.

The single diagnostic that matters

Reproduce the request against your origin directly, bypassing the proxy entirely, and look at exactly what comes back.

# Force the hostname to resolve to your origin address, skipping the proxy.
curl -sv --resolve example.com:443:ORIGIN_IP https://example.com/the/failing/path \
  -o /dev/null 2>&1 | tail -30

You are looking for three things: whether a status line arrives at all, whether the connection closes early, and whether anything odd appears in the headers.

If the direct request succeeds cleanly and the proxied one 520s, the difference is in what the proxy sends. Compare the two request header sets, because something in the proxied request is triggering behaviour the direct one does not: a header your application chokes on, a different Host value, or a body size the origin handles differently.

Then test the protocol explicitly, because the HTTP/2 case is common enough to rule out early:

curl -sI --http1.1 --resolve example.com:443:ORIGIN_IP https://example.com/
curl -sI --http2   --resolve example.com:443:ORIGIN_IP https://example.com/

If HTTP/1.1 works and HTTP/2 fails, you have found it. See the next section.

The HTTP/2 mismatch, which is more common than it should be

The proxy negotiates protocol with your origin using ALPN. If your origin advertises HTTP/2 support during the TLS handshake, the proxy will speak HTTP/2 to it.

The failure happens when the origin advertises support it does not correctly implement. This occurs with older web server builds, certain proxy modules in front of the application, and some load balancer configurations. The handshake succeeds, the proxy sends an HTTP/2 request, and the origin produces something that is not a valid HTTP/2 response.

Two fixes, and either is fine. Disable HTTP/2 to the origin in your proxy’s protocol settings, which is a single toggle and immediately confirms the diagnosis. Or fix the origin so it stops advertising a protocol it cannot serve, which is the more correct answer.

This is worth checking early on any 520 that appeared after a web server upgrade, a proxy module change, or the migration of an origin behind a new load balancer, because those are exactly the events that change what ALPN advertises.

Crashed workers, and the response that stops mid-sentence

The other large category is a process dying while handling the request.

A PHP-FPM worker segfaulting, a Node process killed by the kernel for memory, an application worker hitting a fatal error after headers were already sent: each produces a connection that closes before the response is complete.

The clue is in the origin’s error log rather than the access log, and it is worth being specific about which log:

# The web server's error log, not the access log.
sudo tail -100 /var/log/nginx/error.log

# The application process manager, if separate.
sudo journalctl -u php8.3-fpm --since "30 minutes ago" | grep -i -E 'exit|signal|segfault'

# And the kernel, for out-of-memory kills.
dmesg -T | grep -i -E 'out of memory|killed process' | tail

An entry mentioning a signal, a segfault, or a premature end of script headers is your answer. So is an out-of-memory kill, and that one is more common than people expect on small instances handling occasional large requests.

Header size is worth a specific mention because it is easy to miss. If your application sets a very large cookie, or an authentication header carrying a large token, the response headers can exceed the buffer sizes configured in your web server or the proxy’s limits. The symptom is a 520 on exactly the routes where the large header is set, and nothing anywhere else, which is a maddening pattern until you look for it.

Working through it in order

A sequence that finds most 520s inside ten minutes.

  1. Is it every request or specific paths? Specific paths point at the application. Everything points at protocol or infrastructure.
  2. Curl the origin directly with an explicit resolve. If it fails there, the proxy is not involved and you have a much simpler problem.
  3. Test HTTP/1.1 against HTTP/2. If only HTTP/2 fails, disable HTTP/2 to origin and confirm.
  4. Read the web server error log and the process manager journal, not the access log.
  5. Check the kernel log for out-of-memory kills.
  6. If it is path-specific, check header and cookie sizes on those routes.
  7. Check whether authenticated origin pulls are enabled but the origin is not configured to present the expected client certificate, which produces this error too.

That last one catches people who enabled a security feature at the proxy and did not complete the origin half of the configuration. It produces a total 520 immediately after the change, which makes the correlation obvious once you know to look.

Keep a record of the proxy’s request identifier from the error page. If you do end up contacting support, that identifier plus the timestamp is what lets them find the specific failed request rather than guessing.

How this fits the rest of the stack

A 520 is nearly always a mismatch between two things you are separately responsible for, the proxy’s expectations and the origin’s behaviour, and the number of such mismatches scales with how many layers you operate yourself. Where the routing between the edge and the service is internal to the platform, this whole class of error has nowhere to occur. The RunxBuild hosting calculator prices that shape, and runtime logs sit next to the deploy that produced them rather than in a separate place you have to go and correlate.

Useful related references:

FAQ

What does error 520 mean?

The proxy received a response from your origin that it could not interpret as valid HTTP. That includes an empty reply, a malformed status line, headers exceeding size limits, a connection closed mid-response, or a protocol mismatch. It is a catch-all, which is why it is vaguer than the other 5xx codes.

What is the difference between error 520 and 522?

A 522 means the proxy could not get a response at all, either failing to establish a connection or receiving nothing within the timeout. A 520 means the origin did respond, but with something invalid. A 522 points at firewalls and overload; a 520 points at protocol mismatches and crashed workers.

Can HTTP/2 cause a 520 error?

Yes, and it is a common cause. If your origin advertises HTTP/2 support through ALPN but does not implement it correctly, the proxy will speak HTTP/2 and receive an invalid response. Test with curl using —http1.1 and —http2 separately; if only HTTP/2 fails, disable HTTP/2 to the origin.

Why do I only get 520 errors on certain pages?

Path-specific 520s usually mean the application is crashing on those routes or setting unusually large response headers. Check the web server error log for premature end of script headers or signals, and check cookie and header sizes on the affected routes against your buffer configuration.

How do I debug a 520 error?

Bypass the proxy and request the same path directly against your origin address using curl with an explicit resolve. That tells you immediately whether the origin is producing an invalid response on its own or only when the proxy is involved, which splits the problem in half before you read a single log.

#error 520#unknown error#cloudflare 5xx#http/2#origin server