Skip to content
Latchkey

How to Debug a Cache That Never Hits in GitHub Actions

A cache that never hits almost always means the key changes every run, the path is wrong, or the save step never ran.

When Cache not found for input keys shows on every run, the cause is usually a key that varies each time (a timestamp or github.sha), a path mismatch between save and restore, an OS mismatch, or a save that never happened because the job failed.

Checklist

  • Is the key stable? A key with github.sha or a date changes every run; key on the lockfile instead.
  • Do the save and restore paths match exactly, including the same runner.os?
  • Did the saving run succeed? actions/cache saves in a post-step only if the job did not fail early.
  • Did the first run actually create the cache? The very first run is always a miss.

Workflow

.github/workflows/ci.yml
steps:
  - uses: actions/checkout@v4
  - id: cache
    uses: actions/cache@v4
    with:
      path: ~/.npm
      key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        npm-${{ runner.os }}-
  - run: echo "cache-hit=${{ steps.cache.outputs.cache-hit }}"
  - run: npm ci

Gotchas

  • Enable step debug logging (ACTIONS_STEP_DEBUG=true) to see the resolved key and which entry was restored.
  • If hashFiles returns an empty string, your glob matched no files and the key collapses; check the path.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →