01
Preserve expected and received integrity evidence
Record the package, resolved source, expected integrity, received integrity, and the failing command from the relevant diagnostics. Keep private registry URLs or credentials out of public reports.
Our fixture’s manifest and lockfile stayed consistent while the local .tgz bytes changed. That produced EINTEGRITY, not the separate npm ci error for an out-of-sync dependency declaration. The artifact was still a valid archive; its content differed from the locked expectation.
02
Inspect the artifact source before changing inputs
Compare the resolved path or source with the intended dependency. A local file overwritten in place, a registry/proxy inconsistency, and actual cache corruption require different repairs.
In the lab, two synthetic packages had the same name and version but different module contents. Replacing one tarball path with the other isolated the byte mismatch. It did not demonstrate a public registry publishing or security incident.
03
Check the cache without treating it as the presumed cause
npm’s cache performs integrity checks, and cache diagnostics can help when evidence actually points there. The following commands inspect its configured location and verify the cache; verification may maintain cache metadata.
Our failure was reproduced with a fresh test cache, so deleting a working shared cache was unnecessary. A cache operation cannot make an untrusted replacement artifact become the reviewed original.
npm config get cache
npm cache verify04
Restore the trusted dependency contract
For the controlled local case, restoring the original tarball repaired the mismatch without touching package-lock.json. For a real project, obtain the expected package through its trusted distribution path and investigate why different bytes were served.
If a dependency change is intentional, review the new version/source and lockfile through the normal update process. Do not merely paste a newly observed checksum into a lockfile to suppress a failure whose origin is unknown.
# After correcting the trusted artifact source, in a disposable checkout:
npm ci --ignore-scripts05
Verify the installed result and unchanged inputs
The repaired test installed from a separate fresh cache, loaded the module’s original expected value, and retained the exact lockfile bytes. That made the before/after artifact comparison explicit.
For an application, run the required build and tests under its approved lifecycle policy. An integrity match proves correspondence with the selected bytes; it is not a complete assessment of what a dependency does or whether the reviewed dependency is appropriate.
Know the limits
Reproduced with npm 12.2.1 and Node.js 24.22.1 in a disposable Linux container using local fixtures, with external networking disabled during tests. A valid local tarball was replaced with different valid package bytes at the same path. ci against a fresh cache returned EINTEGRITY. Restoring the original tarball allowed installation with the lockfile unchanged. Real registry/CDN incidents and malicious package detection were not tested.
Sources & further reading
A technical publication by CoreTrailKit.
Browse all articles