Debug-action-cache
Self-hosted runners can persist caches on disk. debug-action-cache here means inspecting the runner's local drive.
# On the self-hosted machine
sudo find / -name "node_modules" -path "*/actions-runner/_work/*" -type d
You might find that previous jobs did not clean up, and the restore step is simply finding a local folder, bypassing the remote cache entirely.
The Debug Action Cache is a mechanism designed to improve the efficiency of debugging processes by caching the results of expensive debug actions. This allows developers to quickly retrieve previously computed results, reducing the time and resources required for debugging.
Cache restore log (failure):
Cache not found for key: ubuntu-latest-npm-d41d8cd98f00b204e9800998ecf8427e
Cache save log (success but missing later):
Cache saved successfully with key: ubuntu-latest-npm-abc123...
hashFiles output:
hashFiles('package-lock.json') = d41d8cd98f00b204e9800998ecf8427e
"debug-action-cache is a CI build cache that stores and restores action outputs keyed by inputs to speed repeat runs and aid debugging."
Would you like a different length or to tailor this for a specific CI system?
actions/cache in GitHub Actions involves enabling debug logging to inspect key generation, understanding that caches are immutable and branch-scoped, and addressing storage limits. Key troubleshooting steps include verifying
accuracy, checking paths, and managing cache keys to resolve cache misses or failed restorations. For detailed guidance, consult the GitHub Actions Caching Documentation Dependency caching reference - GitHub Docs
To debug cache issues in GitHub Actions (specifically when using actions/cache), you should focus on verifying cache hits/misses, inspecting key generation, and enabling verbose logging. 1. Enable Verbose Debug Logging
The most effective way to see exactly what the cache action is doing—such as why a key didn't match or where it’s looking for files—is to enable debug mode for your runner.
Set Secrets: In your GitHub repository, go to Settings > Secrets and variables > Actions and add the following as repository secrets:
ACTIONS_STEP_DEBUG: Set to true to see detailed step output. debug-action-cache
ACTIONS_CACHE_DEBUG: Set to true for specific, deep technical logs related to cache upload/download. 2. Verify Cache Hits and Misses in Logs
Check the Actions tab for your workflow run. Expand the "Post" or "Restore" steps for the cache to see the status: Success: You will see Cache restored from key: .
Failure (Miss): You will see Cache not found for input keys: .
Potential Issue: If you see Cache restored... but your build is still slow, your path might be incorrect, or the files are being overwritten by your build tool. 3. Inspect and Manage Caches via UI
GitHub provides a management interface to see what is currently stored: Navigate to your repository on GitHub. Click the Actions tab. In the left sidebar, under Management, click Caches.
Action: Here you can see cache sizes, last used dates, and delete problematic caches to force a fresh rebuild. 4. Common Troubleshooting Scenarios
Invalid Cache Keys: If your cache never hits, ensure your hashFiles function is pointing to the correct dependency file (e.g., package-lock.json or go.sum). Use key: $ runner.os -build-$ hashFiles('**/package-lock.json') to ensure the cache invalidates only when dependencies change.
Path Mismatches: Ensure the path you are caching actually exists. For example, pip cache is often in a different location than your project folder; use commands like pip cache dir to find the exact path.
Cross-OS Issues: Caches are typically isolated by operating system. A cache created on ubuntu-latest will not be available for a windows-latest runner.
Branch Isolation: Caches are isolated by branch. A PR branch can access the main branch cache, but the main branch cannot access caches created in a PR branch. 5. Debugging Tools & Extensions
tmate: Use the mxschmitt/action-tmate action to pause your workflow and SSH into the runner. This allows you to manually check if the files were actually restored to the directory you expected.
Local Testing: Use tools like nektos/act or the GitHub Local Actions VS Code extension to run your workflows locally and test cache logic without waiting for cloud runners.
Are you running into a specific error message, or is the cache simply not restoring as expected? Debug Github Actions - Daniela Baron Self-hosted runners can persist caches on disk
When your CI/CD pipeline starts acting like a "black box"—specifically when GitHub Actions or similar platforms aren't picking up new dependencies or are restoring corrupted environments—you’ve hit a cache invalidation nightmare. "Debug-action-cache" isn't just a task; it's a deep dive into how your build environment remembers the past. 1. The "Ghost in the Machine" Syndrome The most common reason to debug an action cache is a poisoned cache
. This happens when a previous run successfully saved a state that is technically valid but functionally broken.
Your local build works perfectly, but the CI fails with "File not found" or "Version mismatch" even though the package.json requirements.txt looks correct. The Culprit:
action found a matching key from a previous run and restored it, skipping the "install" step that would have fixed the discrepancy. 2. Strategic Invalidation: The "Big Red Button"
If you suspect the cache is the problem, the first step is to force a "cache miss" to see if a clean slate fixes the build. Key Rotation:
Append a version suffix to your cache key in your YAML file (e.g.,
key: v1-$ runner.os -node-$ hashFiles('package-lock.json') ). Changing instantly forces the action to ignore all previous data. Manual Deletion: Manage Caches via GitHub's UI by navigating to Actions > Management > Caches
. This allows you to surgically remove specific entries that might be causing friction. 3. Monitoring the Restore Flow To truly debug, you need to look at the logs in your Action output. Cache Hit:
If the log says "Cache restored from key...", the action did its job, but the data inside might be stale. Cache Miss: If it says "Cache not found for input keys," it means your
function generated a unique string that hasn't been saved yet. Partial Matches:
Check for "restore-keys." GitHub will try to find the closest match if an exact key isn't found. If your restore-keys
are too broad, you might be pulling in a cache from a completely different branch. 4. Advanced Troubleshooting Techniques HTTP Header Inspection:
If you're caching web assets or API responses within your actions, check the HTTP Cache Headers You might find that previous jobs did not
to ensure your CDN or proxy isn't serving old content before the action even runs. Artifact vs. Cache: Remember that are for speeding up future runs (dependencies), while are for saving build outputs (binaries/logs) from the
run. If you need to debug a specific failure, download the Artifact, not the Cache. State Consistency:
In "write-back" scenarios, there is a delay between the action finishing and the cache being fully uploaded to the storage provider. If a job crashes mid-upload, the next run might pull a partial, corrupted archive. Summary Checklist for Debugging Check the Key: actually change when your dependencies change? Verify the Path:
you are caching exactly where the package manager installs files? Audit Permissions: Does the Action have write access to the cache storage? Isolate the Branch: Remember that caches are scoped; a cache created on might not be accessible to depending on your privacy settings. sample YAML configuration
that includes a "debug mode" for automatically rotating cache keys? Managing caches - GitHub Docs
Don't wait for the cache to break. Create a dedicated "Cache Debug" workflow in your repo (.github/workflows/cache-debug.yml):
name: Cache Debugon: workflow_dispatch: inputs: debug_level: description: 'Debug level' default: 'full' type: choice options: ['full', 'basic']
jobs: debug-cache: runs-on: ubuntu-latest env: ACTIONS_STEP_DEBUG: $ github.event.inputs.debug_level == 'full' && 'true' ACTIONS_RUNNER_DEBUG: ${} steps: - uses: actions/checkout@v4
- name: Generate cache key simulation id: sim run: | echo "hash=$(sha256sum package-lock.json | cut -d' ' -f1)" >> $GITHUB_OUTPUT - name: Attempt Cache Restore with Full Debug uses: actions/cache@v4 with: path: node_modules key: debug-$ runner.os -$ steps.sim.outputs.hash restore-keys: debug-$ runner.os - - name: Manual inspection run: | echo "=== CACHE DEBUG REPORT ===" echo "Node modules exist? $([ -d node_modules ] && echo 'YES' || echo 'NO')" echo "Count: $(find node_modules -type f 2>/dev/null | wc -l)"
Run this manually whenever you suspect cache rot. The env block forces debug-action-cache output into the logs.
Look for the [debug] restoreKeys line:
[debug] restoreKeys: [ 'Linux-pip-', 'Linux-' ]
[debug] GET response for key 'Linux-pip-main-2d711b': 404
[debug] GET response for key 'Linux-pip-': 200 (Stored key: 'Linux-pip-staging-9c4a7b')
Insight: Your hashFiles('requirements.txt') changed (maybe a whitespace change), causing the exact key to miss. The restore key Linux-pip- matched a cache from the staging branch instead of main.
In early 2024, actions/cache@v4 introduced significant changes. Debugging V4 requires new flags.
Why would you need to debug? Here are the top five disasters debug-action-cache helps you solve: