Introduction
The npm ci command performs a clean install based strictly on package-lock.json, verifying the integrity checksum of every downloaded package. When a package's downloaded tarball does not match the integrity hash stored in package-lock.json, npm aborts with EINVAL: invalid argument, read or Integrity checksum failed. This error commonly occurs when the lock file was generated on a different registry (like a private npm proxy), when a package was republished with different content (a rare but serious security event), or when the npm cache is corrupted.
Symptoms
npm ERR! code EINTEGRITY
npm ERR! sha512-abc123... integrity checksum failed when using sha512: wanted sha512-abc123... but got sha512-def456... (45678 bytes)Or:
npm ERR! sha1-xyz789 integrity checksum failed when using sha1:
wanted sha1-xyz789 but got sha1-abc123. (12345 bytes)Or with registry proxy:
npm ERR! 404 Not Found - GET https://registry.npmjs.org/my-private-package/-/my-private-package-1.2.3.tgz
npm ERR! notarget No matching version found for my-private-package@1.2.3Common Causes
- Corrupted npm cache: Cached tarball differs from what the registry now serves
- Package-lock.json generated on different registry: Private registry hashes differ from public npm
- Package republished: A maintainer unpublished and republished a version with different content
- Corporate proxy modifies packages: MITM proxy alters package contents, changing the hash
- Outdated npm version: Older npm versions calculate integrity differently
- Git-based dependencies changed: A git dependency's commit was force-pushed with different content
Step-by-Step Fix
Step 1: Clear npm cache and retry
```bash # Clear the cache forcefully npm cache clean --force
# Verify cache integrity npm cache verify
# Retry the install npm ci ```
Step 2: Regenerate package-lock.json
If the cache clean does not help, the lock file may be out of sync:
```bash # Delete the lock file and node_modules rm -rf node_modules package-lock.json
# Fresh install (generates new lock file) npm install
# Commit the new lock file git add package-lock.json git commit -m "Regenerate package-lock.json"
# Now npm ci should work npm ci ```
Step 3: Configure registry correctly
```bash # Set the correct registry npm config set registry https://registry.npmjs.org/
# For private packages, use .npmrc cat > .npmrc << 'EOF' registry=https://registry.npmjs.org/ @myorg:registry=https://npm.pkg.github.com/ //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} EOF
# Verify registry configuration npm config get registry ```
Step 4: Handle corporate proxy checksums
If behind a corporate proxy that modifies packages:
```bash # Disable integrity check (not recommended for security) npm ci --ignore-scripts
# Or configure npm to use the corporate registry npm config set registry https://npm-proxy.company.com/ npm config set cafile /path/to/corporate-ca.pem ```
Prevention
- Always commit
package-lock.jsonto version control - Use
npm ciin CI/CD pipelines, notnpm install - Pin exact versions in
package.json(not ranges) for production dependencies - Run
npm auditregularly to detect compromised packages - Add a CI step that verifies
npm cisucceeds with the committed lock file - Use
npm cache verifyas part of your deployment health checks - Configure
.npmrcin the repository root for consistent registry settings across the team