npm cache corruption in Docker builds: how to fix
Fixes npm cache corruption inside Docker builds. Use when npm ci fails intermittently in Docker with checksum or integrity errors, builds work locally but fail in the image build, or node_modules ends up half-installed. Covers cache verification, lockfile drift, and BuildKit cache mounts. Not for registry auth failures, Dockerfile syntax errors, or runtime missing modules.
TL;DR
npm cache corruption in Docker builds usually is not corruption at all: it is a lockfile that drifted from package.json, a stale layer cache, or a half-written node_modules from a killed build. Verify with npm cache verify, rebuild the dependency layer without cache, and pin the lockfile into the image build. If the failure mentions integrity checksums, the lockfile and the registry disagree, and the lockfile wins the investigation.
Error / query
npm cache corruption in Docker builds: how to fixUse this skill when
npm cifails in Docker with EINTEGRITY or checksum errors- The same install works on a developer machine
- node_modules in the image is incomplete or inconsistent
- Failures are intermittent across builds
Not for this skill when
- npm cannot reach the registry at all (network/auth)
- The Dockerfile has a syntax error (build problem)
- The app fails at runtime with missing modules (different diagnosis)
Steps
Step 1: Reproduce with a clean dependency layer
COPY package.json package-lock.json ./
RUN npm ci --no-audit --no-fundExpected: copying only the manifests first isolates the dependency layer. If this layer fails, the problem is in the manifests or registry, not your app code. Build with --no-cache-filter on this stage to rule out stale layers.
Step 2: Verify the npm cache and clear it if corrupt
docker build --progress=plain --target deps -t debug:deps . 2>&1 | grep -i "integrity\|corrupt\|EINTEGRITY" | head -5Expected: integrity errors name the exact package and expected vs actual hash. If the cache is genuinely corrupt, add npm cache clean --force before npm ci in the Dockerfile, or better, stop persisting the npm cache between builds and let npm ci work from the lockfile alone.
Step 3: Check for lockfile drift
git diff --stat package.json package-lock.json
npm ci --dry-run 2>&1 | head -5Expected: package.json and package-lock.json change together. Drift (package.json edited without regenerating the lockfile) makes npm ci fail deterministically while npm install works locally, which looks exactly like cache corruption.
Step 4: Use a BuildKit cache mount instead of layer caching for npm
RUN --mount=type=cache,target=/root/.npm npm ci --no-audit --no-fundExpected: the npm cache lives in a BuildKit cache mount, shared across builds but isolated from image layers. Corruption in one build does not poison the layer cache, and you can bust it independently when needed.
Variant phrasings
"npm ci EINTEGRITY docker"
Integrity errors mean lockfile vs registry disagreement. Step 3 first.
"npm install fails only in docker build"
Steps 1 and 3. Local npm install tolerates drift that npm ci in Docker does not.
Why it happens
npm ci is strict by design: it deletes node_modules and installs exactly what the lockfile says, verifying every checksum. Local npm install is lenient and heals drift silently. Docker layer caching then freezes whichever result the first build produced, so a transient registry hiccup or a drifted lockfile gets baked into the cache and replayed as corruption on every subsequent build.
Edge cases and pitfalls
- Private registries with flaky proxies serve truncated tarballs that fail integrity checks intermittently; the fix is the proxy, not npm.
npm cineeds the lockfile present; a .dockerignore that excludes it produces a confusingrequires existing lock fileerror.- Node version drift between local and image changes which binaries get built; pin the base image tag.
- Cache mounts are per-builder; a fresh CI runner starts with an empty mount, so the first build after rotation is always slow.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_zLG0--6FeTGDSbP-ydwj4g
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.