GitHub Actions "Cache already exists" - Entries Are Immutable
GitHub Actions cache entries are immutable. Saving the same key again is a no-op (with a warning), so if your cached contents changed but the key did not, the new contents are never stored.
What this error means
A save step warns that the cache already exists and does not upload, leaving a later run to restore stale contents because the key never changed.
Warning: Cache save failed: Unable to reserve cache with key
npm-cache, another job may be creating this cache. Reserve cache failed.
# or: a cache entry for the key already exists and was not overwrittenCommon causes
Re-saving an existing key
Once a key is populated, that entry is fixed. A second save with the same key does nothing, so updated contents are silently not stored.
Key not derived from the inputs that change
If the cache contents depend on files the key does not hash, the key stays the same while contents drift, and the cache never updates.
How to fix it
Derive the key from what changes
Include a hash of the inputs that affect the cached output so a content change produces a new key.
- uses: actions/cache@v4
with:
path: ~/.cache/build
key: build-${{ runner.os }}-${{ hashFiles('lock', 'config.toml') }}
restore-keys: |
build-${{ runner.os }}-Roll the key when you must refresh
- Bump a version prefix in the key (v2-...) to force a fresh entry.
- Use restore-keys so the previous entry still serves a warm start.
- Do not expect a re-save of the same key to update the contents.
How to prevent it
- Hash every input that changes the cached output into the key.
- Use a version prefix you can bump to invalidate a cache.
- Treat cache entries as write-once per key.