GitHub Actions cache key collision / immutable cache not updating
Cache entries in GitHub Actions are immutable: once a key is saved it cannot be overwritten, so reusing a static key while the underlying content changes leaves you restoring stale data forever.
What this error means
Builds keep restoring outdated dependencies or artifacts even though inputs changed, and the save step reports the key already exists instead of updating it.
github-actions
Cache hit on key: deps-cache (stale)
Cache already exists, not overwriting immutable entry.Common causes
Static key that never changes
A constant key (deps-cache) is restored on every run and can never be updated, so the first saved content sticks.
Key not tied to content hash
The key does not include a hash of the inputs (lockfile), so changed inputs map to the same immutable entry.
How to fix it
Make the key content-addressed
- Include hashFiles of the lockfile or inputs in the primary key.
- Add restore-keys prefixes for partial reuse across changes.
- Let a new hash produce a new entry instead of overwriting.
.github/workflows/ci.yml
key: ${{ runner.os }}-deps-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-deps-How to prevent it
- Always derive cache keys from a content hash.
- Never reuse a static key for changing content.
- Use restore-keys for graceful partial hits.
Related guides
GitHub Actions cache key changes every run (never hits)Fix a GitHub Actions cache that never hits because the key includes a value that changes on every run, such a…
GitHub Actions "Failed to save cache: reserveCache ... Cache already exists"Fix GitHub Actions "Failed to save cache: reserveCache failed: Cache already exists" - two jobs raced to save…
GitHub Actions "Cache not found for input keys"Understand GitHub Actions "Cache not found for input keys" from actions/cache - no entry matched the primary…