[BUG] claude.ai/design blank page — CDN double-compresses assets (Content-Encoding mislabeled) when Accept-Encoding includes brotli

Resolved 💬 1 comment Opened Jul 1, 2026 by ernsyn Closed Jul 1, 2026

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, no no-transform, no content-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>

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗