The EINTEGRITY error in GitHub Actions occurs when cached npm packages don't match the checksums in package-lock.json. The fix involves invalidating the cache, using proper cache keys, or switching to npm ci.
The EINTEGRITY error occurs when npm detects a mismatch between the cryptographic hash (SHA-512 checksum) of a downloaded package and the expected hash stored in your package-lock.json file. npm uses these integrity checksums to verify that packages haven't been corrupted, modified, or tampered with during download. When GitHub Actions caches npm packages or the node_modules folder, the cached versions can become stale, corrupted, or contain different package versions than what package-lock.json expects. This integrity validation failure prevents npm from installing dependencies, as accepting corrupted packages would compromise your application's security and stability. The error is particularly common when cache keys don't include a hash of package-lock.json, causing the cache to be reused even when dependencies have changed.
GitHub Actions caches can become stale or corrupted. Invalidate the existing cache to force a fresh download.
Option A: Delete cache via GitHub UI
1. Go to your repository on GitHub
2. Click Actions tab
3. In the left sidebar, click Caches
4. Find the cache entry related to npm
5. Click the Delete button next to it
6. Run your workflow again
Option B: Force cache invalidation in your workflow
- name: Cache npm packages
uses: actions/cache@v4
with:
path: ~/.npm
# Adding a version suffix forces a fresh cache
key: ${{ runner.os }}-npm-cache-v2-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-cache-v2-Incrementing v1 → v2 will force GitHub Actions to create a new cache entry.
Your cache key must include a hash of package-lock.json so that when dependencies change, the cache is invalidated automatically:
- name: Cache npm packages
uses: actions/cache@v4
with:
path: ~/.npm # Cache npm's cache directory, NOT node_modules
key: ${{ runner.os }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-cache-
${{ runner.os }}-Key points:
- path: ~/.npm - Cache npm's internal cache directory (faster, OS-agnostic)
- hashFiles('/package-lock.json')** - Creates a new cache entry when dependencies change
- Never cache node_modules directly, as it contains compiled binaries specific to each OS
Add this to your workflow before running npm install or npm ci:
- name: Clear npm cache and verify integrity
run: |
npm cache clean --force
npm cache verify
- name: Install dependencies
run: npm ciFull workflow example:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Cache npm packages
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
- name: Clear npm cache
run: npm cache clean --force
- name: Install dependencies
run: npm cinpm ci (clean install) is designed for CI/CD environments and respects package-lock.json strictly:
- name: Install dependencies
run: npm ciWhy use npm ci over npm install:
- Respects exact versions in package-lock.json (no semver flexibility)
- Fails fast if package-lock.json is out of sync with package.json
- Faster and more reliable in CI environments
- Prevents "works on my machine" issues
If npm ci fails with EINTEGRITY, the issue is definitely cache-related, not a code problem.
Different versions of Node.js and npm use different hash algorithms. Lock down your Node version:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18.17.0' # Use exact version, not just '18'
node-version-file: '.nvmrc' # Or read from .nvmrc fileAdd an .nvmrc file to your repository root:
18.17.0All team members should use the same Node/npm versions locally using nvm or fnm.
Ensure package-lock.json is committed and up-to-date:
# Locally: regenerate lock file with current npm
rm package-lock.json
npm install
git add package-lock.json
git commit -m "Refresh package-lock.json with current npm version"
git pushVerify lock file is in git:
git ls-files | grep package-lock.jsonNever delete package-lock.json as a permanent fix—it removes integrity checking entirely.
GitHub Actions Cache Service Behavior:
- Cache size limits: GitHub Actions allows up to 5GB of cache storage per repository (shared across all branches)
- Cache isolation: Caches from pull requests can only read (not write to) caches from the default branch
- Concurrent job safety: When matrix jobs run simultaneously, ensure cache keys are unique per job
Performance optimization:
- Caching ~/.npm (npm's cache directory) is typically 10-50MB, compared to node_modules which can be 500MB+
- A properly configured cache with hashFiles() can reduce install time from 2-3 minutes to 30-60 seconds
Diagnosing persistent EINTEGRITY errors:
- Check the Actions tab → Caches to see if old cache entries exist
- Review workflow logs for the specific package failing and its integrity hash
- Cross-reference the hash with package-lock.json to confirm mismatch
npm ERR! code E401 npm ERR! 401 Unauthorized - Token has expired
Token has expired - npm authentication failure
npm ERR! code EAI_NODATA npm ERR! errno EAI_NODATA npm ERR! getaddrinfo EAI_NODATA registry.npmjs.org
How to fix "npm ERR! code EAI_NODATA - getaddrinfo EAI_NODATA"
npm ERR! code EMPTYPACKAGE npm ERR! Package contains no files
How to fix 'npm ERR! code EMPTYPACKAGE' - Package contains no files
npm ERR! code EWORKSPACEMISSING npm ERR! Workspace does not exist: packages/missing
How to fix "npm ERR! code EWORKSPACEMISSING - Workspace does not exist" error
npm ERR! code EADDRNOTAVAIL npm ERR! errno EADDRNOTAVAIL npm ERR! Address not available
How to fix "npm ERR! code EADDRNOTAVAIL - Address not available" error