Problem
A SvelteKit SSR page (~274KB response) hung indefinitely in Chrome and Brave. The browser tab spinner never stopped and Chrome itself became unresponsive (couldn't quit). A different user in a different browser also couldn't load the same page. Meanwhile:
curlloaded the page in <600ms- Headless Chrome (Puppeteer) loaded it fine
- SPA navigation (clicking into the page without a full reload) worked perfectly
The hang occurred on any full-page navigation (SSR round-trip) — refreshing the page, hitting a bookmark, or pasting the URL. Client-side SvelteKit navigation worked fine.
Root cause
The app was behind Cloudflare (via Render's managed CDN), which advertises HTTP/3 via alt-svc: h3=":443"; ma=86400. Chrome and Brave learn this header and upgrade subsequent connections to QUIC. A QUIC flow-control stall on the SSR response caused the hang.
Evidence:
curl(no HTTP/3 support on the machine) used HTTP/2 over TCP → worked fine- Fresh headless Chrome (no cached
alt-svc) used HTTP/2 → worked fine - Real browsers had cached the
alt-svcheader from prior visits → used QUIC → hung - Disabling QUIC in
chrome://flags/#enable-quic→ page loaded instantly
Diagnosis steps
- Disable QUIC:
chrome://flags/#enable-quic→ Disabled → relaunch → test the page. If it loads: QUIC confirmed. - Check active QUIC sessions:
chrome://net-internals/#quicduring a hang - Check alt-svc cache:
chrome://net-internals/#alt-svcfor cached entries - If not QUIC: Capture
chrome://net-export/trace and analyze at https://netlog-viewer.appspot.com/
Fix (application level)
Reduce exposure by avoiding unnecessary full-page SSR round-trips. In our case, a window.location.href assignment after a form submission forced SSR when invalidate('space:data') (client-side data refresh) was the correct pattern. But this only eliminates one trigger — any user refreshing the page or following a direct link still hits SSR and can hang.
Fix (infrastructure level)
To disable QUIC server-side on Cloudflare-managed domains:
- If you control Cloudflare: Dashboard → Network → HTTP/3 (QUIC) → Off
- If behind managed Cloudflare (e.g., Render): File a support ticket asking them to disable HTTP/3 for your domain. You cannot set
Alt-Svc: clearfrom the origin — Cloudflare strips/overrides the origin'sAlt-Svcheader at the edge.
Key insight
When curl works but real browsers hang on the same URL, the transport layer (HTTP/3 vs HTTP/2) is the prime suspect. curl typically doesn't support HTTP/3 and uses TCP, while browsers upgrade to QUIC after caching the alt-svc header. The chrome://flags/#enable-quic toggle is the fastest diagnostic.