Cache Not Found for Input Keys: Causes and Fixes
Last updated
Cache not found for input keys is a cache miss from actions/cache: no saved cache matched your key or restore-keys, so the step carries on without restoring anything. It is a warning in most workflows and the job continues, but if your next step needs the cache it can look like a failure. This page explains why the cache was not found and how to make it hit. Rules are from GitHub's dependency caching reference, checked October 2026.
The exact message
Cache not found for input keys: Linux-npm-3f1c0d9a2b..., Linux-npm-
For actions/cache/restore with fail-on-cache-miss: true you instead get a failed step. The first key listed is your key, the others are your restore-keys. A miss on the first run for a new key is normal: the post step saves the cache, and later runs hit it.
How the lookup works
- The action looks for an exact match on
keyin the current branch. - If none, it looks for prefix matches on
key, then eachrestore-keysentry, in order. With several partial matches it returns the most recently created cache. - If none, it repeats the search on the default branch.
Scope rules: a run can restore caches from the current branch or the default branch, and pull requests can also restore from the base branch. It cannot restore caches from sibling or child branches. Tag caches are isolated per tag. Entries not accessed for 7 days are removed, and the default limit is 10 GB per repository.
Causes, most likely first
1. It is the first run for this key
Any new key misses once. If your key includes hashFiles('**/package-lock.json'), every lockfile change misses once. Nothing to fix. Add restore-keys so a near match restores something:
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-${{ runner.os }}-
2. The key changes on every run
Keys like ${{ github.sha }}, ${{ github.run_id }} or a timestamp never match a previous run. Key on the file that determines the content (the lockfile), not the commit. The cache key builder generates safe keys.
3. The cache lives on a branch you cannot read
A feature branch saves its cache under that branch. A different feature branch cannot see it. Pull request runs save caches for the merge ref, so one PR does not warm another. Fix: make sure the default branch saves the cache, for example with a push-to-main workflow or a scheduled run, so every branch can fall back to it.
on:
push:
branches: [main]
schedule:
- cron: "0 3 * * *"
4. The cache was evicted
After 7 days without access, or when the repository goes over 10 GB, entries are deleted, least recently used first. Check Actions, then Caches in the repository, or run gh cache list. Details and fixes in GitHub Actions cache limits.
5. The path or runner.os differs
The cache is tied to its key and also its version, derived from the paths and compression method. Changing path, or restoring on a different OS than it was saved on, produces a miss. Include runner.os in the key, and keep the path identical in save and restore.
6. The save never happened
The post step saves only if the job succeeded and the key had no exact hit. If the job failed before the end, nothing was saved. Use actions/cache/save with if: always() when you want to save after failure:
- uses: actions/cache/restore@v4
id: cache
with: { path: ~/.cache/pip, key: pip-${{ hashFiles('requirements.txt') }} }
- run: pip install -r requirements.txt
- uses: actions/cache/save@v4
if: always() && steps.cache.outputs.cache-hit != 'true'
with: { path: ~/.cache/pip, key: pip-${{ hashFiles('requirements.txt') }} }
7. Two jobs race to save the same key
Cache entries are immutable. If two matrix cells save the same key, one wins and the other logs a reserve error. Give each cell its own key or save from one job.
Use the cache-hit output
cache-hit is true only on an exact key match, not on a restore-key match. Use it to skip work:
- uses: actions/cache@v4
id: cache
with:
path: node_modules
key: nm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
- if: steps.cache.outputs.cache-hit != 'true'
run: npm ci
Remember that a restore-key hit sets cache-hit to false while still restoring files.
When caching is not helping
If caches keep missing, are huge, or restores are slower than the install they replace, a runner with warm local caches may be a better answer. compiler.dev machines keep dependency, git and Docker layer caches ready, so you do not manage keys for those; see pricing. Other options: GitHub Actions caching and Docker layer caching. Large caches also cause No space left on device.
How to prevent it
- Key on lockfiles, add a
restore-keysfallback, and includerunner.os. - Save caches from the default branch so every PR can restore them.
- Keep total cache size well under 10 GB.
- Check the hit rate in your logs weekly, and use the cache hit savings estimator to see what a miss costs.
FAQ
Is "Cache not found for input keys" an error?
No, it is an informational message about a miss. The job continues unless you set fail-on-cache-miss: true.
Why do I get a cache miss on every pull request?
PR caches are scoped to the merge ref, and a PR can only restore from itself, its base branch and the default branch. Make sure the default branch saves the cache.
How long does a GitHub Actions cache last?
Seven days since the last access, unless evicted earlier for exceeding the repository limit.
Why does my cache restore but cache-hit is false?
A restore-key (prefix) match restores files but does not count as an exact hit, so cache-hit is false.
Related
- Cache Cargo and Rust Builds in GitHub ActionsCache the Cargo registry, git dependencies and target directory in GitHub Actions with Swatinem/rust-cache or actions/cache, and avoid bloated caches.
- Cache Go Modules and Build Cache in GitHub ActionsCache Go modules (GOMODCACHE) and the build cache (GOCACHE) in GitHub Actions with setup-go or actions/cache. Keys, go.sum, and verifying hits.
- Cache Gradle Builds in GitHub ActionsCache Gradle dependencies and build cache in GitHub Actions with gradle/actions/setup-gradle or actions/cache. Keys, read-only PRs, cleanup and checks.
- Cache npm Dependencies in GitHub ActionsCache npm dependencies in GitHub Actions with setup-node or actions/cache. Working YAML, the right key, why not node_modules, and how to confirm a hit.