All posts
javascriptbundling

Fixing "ChunkLoadError: failed to load chunk"

Why webpack's ChunkLoadError happens after deployments and under network issues, and how to fix and prevent it.

SR

Suhail Roushan

August 6, 2026

·
5 min read
·
0 views

ChunkLoadError: Loading chunk X failed is webpack's version of the same underlying problem across bundlers: a code-split JavaScript chunk that the running application needs failed to load — most commonly because the deployed build changed since the page was first loaded, but also sometimes because of a genuine network failure or an overly aggressive cache.

This error means webpack's runtime attempted to load a specific numbered or named chunk (a piece of your application's code split out for lazy loading) and the request failed — either the file no longer exists at that URL (stale client after a deployment), or a network-level failure prevented the fetch from completing even though the file exists.

Why This Error Happens

Webpack splits your application into multiple JavaScript files (chunks), loaded on demand as the user navigates or triggers features requiring code not included in the initial bundle. ChunkLoadError fires when the webpack runtime's chunk-loading mechanism can't successfully load one of these files — the two dominant causes are a deployment having replaced the old chunk with a new, differently-named one (stale client) or a transient network issue (poor connectivity, a CDN hiccup, an ad blocker interfering with a request) preventing an otherwise-available file from loading.

Reproducing and Diagnosing the Error

The deployment-staleness scenario (most common in production):

1. User loads app; webpack runtime has a manifest mapping chunk IDs to
   filenames like chunk.3.a1b2c3.js
2. New deployment: chunk.3 is now chunk.3.f9e8d7.js (different hash)
3. User's already-loaded runtime still has the OLD manifest in memory,
   tries to fetch chunk.3.a1b2c3.js
4. That file was removed during deployment → 404 → ChunkLoadError

Distinguishing from a genuine network issue — check whether the error correlates with recent deployments (staleness) or is scattered across time and users regardless of deploy timing (more likely network-related):

window.addEventListener("error", (event) => {
  if (event.message?.includes("ChunkLoadError")) {
    // Log deployment timestamp alongside error timestamp to check correlation
    logError({ error: event.message, timestamp: Date.now(), lastKnownDeployTime });
  }
});

Core Concepts Behind This Error

Like the dynamic-import version of this problem in non-webpack bundlers, the deployment-staleness case is fundamentally a stale-client issue, not a code defect — the fix is getting the client to reload and fetch the current build, not changing the import or chunk configuration itself.

Retry logic can meaningfully help with the transient-network-failure case but does nothing for the staleness case — retrying a fetch for a chunk file that was genuinely deleted during deployment will fail identically every time, so retry logic should be paired with, not a substitute for, staleness detection and reload prompting.

Webpack's publicPath configuration affects where chunks are fetched from, and a misconfigured or environment-mismatched publicPath (chunks expected at a different URL than where they're actually hosted) produces a persistent version of this error unrelated to deployment timing — worth checking specifically if the error is consistent and widespread rather than clustered after deploys.

Service workers caching old chunk manifests or files can compound this problem, serving a stale cached chunk reference even after the actual server-side files have changed — applications using service workers for offline support need explicit cache invalidation strategies tied to deployment versioning.

Fixing ChunkLoadError

Fix 1: Catch the error and prompt or trigger a reload, addressing the dominant deployment-staleness cause directly:

window.addEventListener("error", (event) => {
  if (event.message?.includes("ChunkLoadError")) {
    if (confirm("A new version is available. Reload now?")) {
      window.location.reload();
    }
  }
});

// Or catch it at the specific dynamic import call site
import(/* webpackChunkName: "settings" */ "./SettingsPage").catch((err) => {
  if (err.name === "ChunkLoadError") {
    window.location.reload();
  }
});

Fix 2: Add retry logic specifically for transient network failures, distinct from the staleness case, giving genuinely flaky connections a chance to succeed on retry:

async function loadChunkWithRetry(importer: () => Promise<any>, attempts = 2) {
  for (let i = 0; i < attempts; i++) {
    try {
      return await importer();
    } catch (err) {
      if (i === attempts - 1) throw err;
      await new Promise((r) => setTimeout(r, 1000));
    }
  }
}

Fix 3: Verify publicPath configuration matches your actual deployment URL structure if the error is persistent and unrelated to deploy timing, rather than assuming it's always the staleness scenario:

// webpack.config.js
output: {
  publicPath: process.env.CDN_URL || "/", // ensure this matches actual hosting
}

Should You Combine Retry Logic With Reload Prompting?

Yes — retry first for a small number of attempts to handle genuinely transient network blips without disrupting the user, and fall back to a reload prompt if retries are exhausted, since a persistent failure after retries is much more likely to be the staleness scenario that only a fresh page load can resolve. Layering both addresses the two distinct causes appropriately rather than assuming every occurrence is the same root cause.

Preventing ChunkLoadError in Production

Configure your CDN/hosting to retain recently-superseded chunk files for a grace period post-deployment, directly reducing how often already-loaded clients hit a genuinely missing file. Combine short retry logic (for transient network issues) with a reload prompt as a fallback (for the deployment-staleness case) in a global error handler, rather than treating this as an unrecoverable error to just log and ignore.

If ChunkLoadError shows up in your error tracking, check whether occurrences cluster right after deployments — that pattern confirms the staleness cause and points you toward reload-prompting as the fix, rather than debugging a network or configuration issue that isn't actually the problem.

Related posts

Written by Suhail Roushan — Full-stack developer. More posts on AI, Next.js, and building products at suhailroushan.com/blog.

Get in touch