Today I went down a rabbit hole chasing an error that only happened in one very specific setup:
Desktop browsers → no issues
Firefox / Edge on mobile → no issues
Chrome on mobile → constant 520 errors through Cloudflare
On the surface, this looked random. Nginx logs weren’t showing the usual request header too large
message, so it was easy to assume something else was broken (TLS key share, proxy headers, buffer settings, etc.). I tried changing proxy headers, adjusting Cloudflare rules, even toggling TLS quirks. Nothing fixed it.
It turned out to be huge HTTP request headers.
Chrome mobile sends very fat headers after login redirects — especially with cookies + sec-ch-ua
client hints. This combination was blowing past nginx’s default request header size.
Why didn’t nginx log it? Because:
With HTTP/1.1, nginx can return a 431 Request Header Fields Too Large and log it.
With HTTP/2 (used by Cloudflare → origin), nginx sometimes drops the connection during header frame parsing, before it can even send a 431 or log an error. From my perspective it just showed up as "-" 000
in access.log and a Cloudflare 520.
That’s why I never saw a “too large header” error line, and why disabling the Cloudflare proxy (H1 direct) seemed to magically “fix” things.
I raised the nginx header size limits:
client_header_buffer_size 64k;
large_client_header_buffers 16 64k;
http2_max_field_size 32k;
http2_max_header_size 128k;
Once I did that, Chrome mobile + Cloudflare stopped failing.
Modern web headers are big. Between tracking cookies, Auth0 state, and Chrome’s UA-Hints, it’s normal for requests to carry 10KB+ of headers.
HTTP/2 hides the evidence. Oversized headers don’t always produce friendly nginx log messages. You may just see 000 status in access.log + Cloudflare 520.
Incognito can behave differently. With fewer cookies, headers shrink, which explains why Chrome incognito “worked fine.”
Cloudflare proxy can amplify issues. Direct-to-origin H1 requests might succeed, but Cloudflare’s H2 pipeline forces stricter frame parsing.
Default limits are too small. Both nginx and Apache ship with conservative header limits that don’t always match the reality of modern apps.
If you ever run into Cloudflare 520s that happen only on Chrome mobile (but not desktop or other browsers), check your header sizes first. It might just be a “too big to log” header issue.