[BUG] claude.ai/design blank page — CDN double-compresses assets (Content-Encoding mislabeled) when Accept-Encoding includes brotli
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Summary
All claude.ai/design/assets/v1/*.js bundles are served double-compressed with a single, wrong Content-Encoding header whenever the request's Accept-Encoding includes br (which every browser sends). Browsers strip one compression layer, are left with still-compressed bytes, fail silently (HTTP 200, no error), and render a blank white page. Chrome, Firefox, and the Claude desktop app are all affected.
Impact
claude.ai/design is unusable (white screen) in any browser that advertises brotli. The main app is unaffected because its assets come from assets-proxy.anthropic.com (GCS) with cache-control: no-transform; the /design assets come from Cloudflare R2 without no-transform, so Cloudflare re-compresses them.
What Should Happen?
Expected
One compression layer matching the Content-Encoding header, decoding to valid JS — regardless of whether the client offers br, zstd, or both.
Error Messages/Logs
Steps to Reproduce
Reproduction (no login required — asset is public)
U='https://claude.ai/design/assets/v1/index-XXXXXXXX.js' # any current /design .js from DevTools
# BROKEN — browser's Accept-Encoding (contains br). Body is zstd(brotli(JS)); one zstd pass ≠ JS:
curl -s -H 'accept-encoding: gzip, deflate, br, zstd' "$U" | zstd -dq | head -c 16 | xxd
# -> garbage (still brotli-compressed), not "const __vite__..."
# ALSO BROKEN — br alone -> brotli(brotli(JS)):
curl -s -H 'accept-encoding: gzip, deflate, br' "$U" > /tmp/x # one brotli pass still ≠ JS
# CORRECT — zstd WITHOUT br -> clean single-layer zstd(JS):
curl -s -H 'accept-encoding: gzip, deflate, zstd' "$U" | zstd -dq | head -c 20
# -> const ...
Additional tell: two back-to-back fetches of the same static, content-hashed file return different bytes/lengths, and the zstd frame has Check: None (no checksum), so nothing detects the corruption.
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
2.1.197
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Environment
- URL: https://claude.ai/design
- Affected: Chrome, Firefox, Claude desktop app (any client sending
Accept-Encoding: ...br...) - Served from Cloudflare R2 (
x-om-br-source: r2) - Response headers on failing asset:
content-encoding: zstd, nono-transform, nocontent-length(chunked)
Scope
Route-wide, not a single object. Verified 6/6 /design/assets/v1/*.js bundles (including the entry index-*.js and rolldown-runtime, client-lite, preload-helper, useMutation) areall double-compressed under a br-containing Accept-Encoding, and all correct under gzip, deflate, zstd. Because the entry bundle is among the corrupted ones, the app cannot bootstrap at all → fully blank page.
---
<sub>🔍 Root-caused with Claude Code v2.1.197 — reproduced the double-compression via curl/zstd/node, isolated the trigger to Accept-Encoding containing br, and verified it route-wide across 6 /design bundles.</sub>
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗