Lesstep
GitHub Actions · Checked November 3, 2026

GitHub Actions: "Failed to save: Unable to reserve cache with key"

The save at the end of the job did not happen, and the job still passes. The line comes from the cache package of GitHub's actions toolkit, which actions/cache uses, and so do the caches built into setup-node, setup-go, setup-uv and others. Two different endings follow the same start, and they mean different things.

The two lines

The key already exists

From a push to main in pymovements on October 28, 2026 (a pull request to stop it: pymovements #1788):

Run actions/cache/save@v4
...
[command]/usr/bin/tar --posix -cf cache.tzst --exclude cache.tzst -P -C /home/runner/work/pymovements/pymovements --files-from manifest.txt --use-compress-program zstdmt
Failed to save: Unable to reserve cache with key test-ubuntu-latest-py3.13-4ec5...c7b4, another job may be creating this cache.
##[warning]Cache save failed.

Where it usually comes from:

This is harmless when the jobs would save the same files: the job that won saved them, and later runs restore them. It is not harmless when the jobs build different files under one key, for example a matrix of compilers on the same OS. Then the other jobs restore files built for a different setup, so put that matrix value in the key.

Stopping it

Save only when the restore missed, and build the key from the files that decide the contents:

- uses: actions/cache/restore@v6
  id: cache-restore
  with:
    path: ~/.cache/pip
    key: pip-${{ runner.os }}-${{ hashFiles('requirements*.txt') }}
    restore-keys: pip-${{ runner.os }}-

# ... install and test ...

- uses: actions/cache/save@v6
  if: steps.cache-restore.outputs.cache-hit != 'true'
  with:
    path: ~/.cache/pip
    key: ${{ steps.cache-restore.outputs.cache-primary-key }}

This run may only restore

From a pull_request_target run on October 11, 2026 (sc4pac-actions #12):

##[warning]Failed to save: Unable to reserve cache with key sc4pac-download-cache-80c6c006f143. More details: cache write denied: token has no writable scopes

What GitHub suggests:

jobs:
  test:
    runs-on: ubuntu-latest
    cache-mode: read   # read, write, write-only or none
    steps:
      - uses: actions/cache/restore@v6
        with:
          path: ~/.cache/pip
          key: pip-${{ runner.os }}-${{ hashFiles('requirements*.txt') }}

The documentation also says the cache becomes read-only when a repository goes over the budget set for cache storage, until billing is resolved or usage drops under the free 10 GB.

Telling it apart

See failed jobs from IntelliJ IDEA

Pipeline Inbox for GitHub Actions Workflows, a plugin by Lesstep for JetBrains IDEs 2024.1 or later, lists the runs of all your repositories in an IDE tool window, with their jobs and steps, and your current branch's runs are in the status bar. Reading is free; re-running failed jobs, cancelling, running workflows and reviewing deployments are Pro (US$1.50 a month, with a 30-day trial).

GitHub and GitHub Actions are trademarks of GitHub, Inc.; IntelliJ IDEA is a trademark of JetBrains s.r.o. This page is not affiliated with, sponsored or endorsed by GitHub, Inc. or JetBrains.

More: The "Unexpected input(s)" warning · "Artifact storage quota has been hit" · "Input required and not supplied" · "Cache not found for input keys" · GitHub Actions plugins for IntelliJ IDEA compared · 日本語