Build & Deploy · recorded 2026-08-29 · applies to 2 tool(s) ✓ Verified

Problem: White screen for some users after release — ChunkLoadError: Loading chunk N failed (404) —— Trove problem library

Verified 2026-08-29occasional white screen ChunkLoadError after deploy — version mismatch: upload the new dist assets first, overwrite index.html last, keep old assets for at least one release cycle.

Quick fix

# One-liner: fix the release order — assets first, entry last; keep old assets for at least one release cycle
# 1) upload the new dist/ entirely (incl. new hashed assets) 2) upload/switch index.html last

In the release script, move the index.html overwrite to the last step, and keep the old asset directory when uploading.

What you will run into

After publishing a new version, some users see a white screen, and a refresh sometimes recovers; the console shows ChunkLoadError: Loading chunk N failed;

the hashed resource requested by a dynamic import returns 404. You visit it yourself and it's fine — because your cache is fresh.

Why this happens

Version skew: the browser's cached old entry HTML still references old-version hashed chunks, while the server's new release already deleted the old resources.

When the user triggers a dynamic import, the old chunk 404s → module load fails → whole page white.

RoleState
User's browserCaches old entry HTML pointing at old hashed resources
ServerDeployed the new version; old resources deleted
ResultOld chunk 404 → ChunkLoadError → white screen

Vite-built chunk filenames carry content hashes (measured: feature-DP5yDwy7.js → feature-PcJGFbac.js); the hash changes with each version, and old/new HTML reference completely different resources.

Vite build output is "entry HTML + content-hashed chunks": the hash is derived from file contents, so content changes change the hash.

The browser first fetches the entry HTML, then loads chunks at runtime per the references inside it — a two-step fetch with a time gap, during which the server may have deployed a new version and deleted the old chunks.

A cached old HTML points at old hashes; the server no longer has those files → dynamic import 404 → ChunkLoadError. Deterministic takeaway: this is not a code bug, it is version skew between the "client's reference set" and the "server's asset set".

Three fixes: keep old chunks at deploy time (don't delete old dist files / use versioned directories), make the entry HTML non-cacheable (Cache-Control: no-cache while chunks stay long-cacheable), or force a refresh after release.

Diagnosis: in the Network panel the failed URL carries an old hash with no matching file in the server dist.

Step by step

1. Release order: assets first, entry last — Required

Ship hashed static assets first, switch the entry HTML last. Both old and new entries can then find their own resources.

2. Keep old assets for a transition period — Required

Keep old assets for at least one release cycle (especially with back-to-back releases) so users still holding the old entry transition smoothly.

3. nginx fallback must not swallow static-asset 404s — Required

try_files should match real files first, then fall back to index.html — not a blanket fallback:

location / {
  try_files $uri $uri/ /index.html;   # real files first, then fallback
}

4. CDN and Service Worker follow the same version-consistency rules — Required

Design CDN cache policy and SW update logic as "assets before entry" too; don't let a caching layer amplify version skew.

How to confirm it works

Simulate an old user with an old-version entry (expected shape):

curl -H "Cache-Control: no-cache" http://your-domain/feature-PcJGFbac.js
→ HTTP 200 (new hashed asset exists)
curl -I http://your-domain/index.html
→ HTTP 200, referenced asset list consistent with live resources

After release both old and new pages return HTTP 200 (measured: keeping old assets → both 200); consecutive releases no longer produce ChunkLoadError.

Other environments

EnvironmentNotes
Single releaseAssets-first-then-entry solves it
Consecutive releasesKeep old assets for at least one release cycle, or the previous round's users still white-screen
nginx SPA fallbacktry_files $uri first, then fallback; don't swallow static-asset 404s
CDN / Service WorkerSame version-consistency rules as the server
Already-white-screen usersHard refresh or reopen recovers (entry becomes fresh after cache refresh)

Symptom

After release, some users get a blank screen that occasionally recovers on refresh; console reports ChunkLoadError: Loading chunk N failed; hashed resources requested by dynamic import return 404.

Cause

Version mismatch: the browser-cached old entry HTML still references old-version hashed chunks, while the new release has already deleted the old resources -> dynamic import 404 -> module load fails -> full-page blank screen.

Solution

  1. Release order: assets first, entry last (hashed static assets go live first, entry HTML switches last).
  2. Keep old assets during a transition period (cover at least one release cycle).
  3. nginx SPA fallback must not swallow static-asset 404s (try_files matches real files first, then falls back to index.html).
  4. CDN and Service Worker follow the same version-consistency rules.
Verification Evidence
  • Verified locally (2026-08-29): two builds of vite 5.4.21, chunk hash changed (feature-DP5yDwy7.js -> feature-PcJGFbac.js); old chunk HTTP 404 when the server only deployed v2 assets (reproduced); keeping old assets gives both old and new pages HTTP 200 (solution holds).

Evidence details kept locally (2026-08-29)

Applicable tools (2)

This problem is linked from the tool pages below — reachable from either side.

vite-deploynginx

Bundled solutions (combos)

This problem is part of the following verified bundles.

Source & evidence

Recorded Verified ✓ VerifiedApplies to 2 tool(s)
Entries contain locally measured or reviewable-source solutions; unmeasured items are explicitly labeled.

Source: https://juejin.cn/post/7678324462626471946

← Build & Deploy domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk