Problem: Cache restored only 20% of the time.
Logs show: Cache not found for key: linux-npm-xyz123
Check key generation:
- name: Debug cache key
run: |
echo "key: $ runner.os -npm-$ hashFiles('**/package-lock.json') "
ls -la **/package-lock.json
Output shows:
package-lock.json changes every build (e.g., due to npm install --package-lock-only differences).
Fix:
key: $ runner.os -npm-$ hashFiles('package-lock.json')
restore-keys: |
$ runner.os -npm-
Now even if exact key misses, it restores the most recent linux-npm-* cache.
debug-action-cache is a mindset + toolset for making caching transparent. Enable verbose logging, inspect via API, and run dry-restore jobs. Once you see exactly what key is generated, what files are stored, and why a hit/miss happens, fixing cache issues becomes straightforward.
Next step: Add ACTIONS_STEP_DEBUG=true to your repo right now and re-run your last failed workflow – you’ll likely spot the cache issue within minutes.
Maximizing Build Efficiency: A Deep Dive into debug-action-cache
In the world of modern DevOps and CI/CD pipelines, speed is the ultimate currency. As projects grow, build times tend to balloon, often becoming a bottleneck for development teams. To combat this, build systems like Bazel and GitHub Actions utilize "action caching." However, when a cache doesn't behave as expected—either by failing to hit or by returning "poisoned" results—you need a way to look under the hood.
This is where the debug-action-cache flag (or concept) becomes your most valuable tool. What is Action Caching?
Before diving into debugging, it’s essential to understand what we’re fixing. Action caching stores the outputs of specific build steps (actions) based on their inputs. The logic is simple: Input Hash + Command = Output.
If the source code, environment variables, and toolchains remain identical, the system skips the work and pulls the result from the cache. When this breaks, your CI costs spike and developer productivity plummets. Why Use debug-action-cache?
You typically reach for debugging flags when you encounter two specific scenarios:
Cache Misses: You changed one line of a README file, but the entire C++ library is recompiling. Why did the hash change?
Non-Deterministic Builds: Two different machines running the exact same code produce different output hashes, leading to "cache poisoning." How to Debug the Cache: Common Strategies
While different tools have different specific commands, the process of "debugging the action cache" generally follows these steps: 1. Inspecting Input Digests
In systems like Bazel, you can use flags like --execution_log_json_file. This allows you to see the exact metadata sent to the cache. You can compare logs from two different builds to see which file or environment variable caused the discrepancy. 2. Identifying "Dirty" Environment Variables
A common culprit for cache misses is the environment. If your build script pulls in a timestamp, a random seed, or a local file path (e.g., /Users/john/project vs /Users/jane/project), the cache will treat them as different actions. 3. Verbose Logging debug-action-cache
When using GitHub Actions, debugging the cache often involves setting:ACTIONS_STEP_DEBUG: true
This exposes the communication between the runner and the remote cache storage, showing you if the network is failing or if the key lookup is returning a "404 Not Found." The "Cache-Hit" Checklist
If you are struggling with cache performance, run through this list:
Normalization: Are your file paths absolute or relative? Always prefer relative paths for better portability.
Toolchain Consistency: Are all developers and CI runners using the exact same version of the compiler/interpreter?
Ordered Inputs: Some systems are sensitive to the order in which files are listed. Ensure your glob patterns or file lists are sorted.
Stripping Non-Determinism: If you're compiling binaries, ensure you strip timestamps from the output, as these will change the file hash even if the code is identical. The Cost of Ignoring Cache Issues
"Cache flapping"—where the cache is constantly invalidated—isn't just annoying; it's expensive. In a large organization, fixing a 10% cache miss rate can save thousands of dollars in compute credits and hundreds of engineering hours per month. Conclusion
The debug-action-cache workflow is less about a single command and more about a mindset of determinism. By strictly controlling your inputs and using debugging tools to inspect hashes, you can transform a sluggish pipeline into a lightning-fast competitive advantage.
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.
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. Problem : Cache restored only 20% of the time
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
As of mid-2026, GitHub has released Cache v5 (beta) which introduces:
The debug-action-cache philosophy is evolving into structured logging. Instead of raw [debug] lines, you will soon see JSON logs you can pipe into jq.
However, the fundamentals remain: You cannot optimize what you cannot measure. Until GitHub provides a full Cache UI with version history, manual debugging using ACTIONS_STEP_DEBUG remains the most powerful tool in your DevOps arsenal.
The Debug Action Cache is a valuable tool for improving the efficiency of debugging processes. By caching the results of expensive debug actions, developers can quickly retrieve previously computed results, reducing the time and resources required for debugging. With its simple design and flexible implementation options, the Debug Action Cache is an attractive solution for developers seeking to optimize their debugging workflow.
No specific math was used. If I had to pick a formula that relates, it could be: $$time节省 = cache命中率 \times 调试动作时间$$
To debug a GitHub Actions cache issue, the most direct method is to enable Step Debug Logging. This reveals detailed cache keys, hit/miss logs, and download URLs in your workflow run. 🛠️ Essential Debugging Steps
Enable Debug Logs: Create a repository secret named ACTIONS_STEP_DEBUG with the value true.
Verify Cache Keys: Check the hashFiles output in logs to ensure your lockfiles (e.g., package-lock.json) are being picked up correctly.
Check Management UI: Go to Settings > Actions > Caches in your repository to see total size and individual keys.
Isolate Save/Restore: Use actions/cache/restore and actions/cache/save as separate steps to identify if the failure is during download or upload. 📊 Sample Debug Report Data Output shows:
package-lock
When debug logging is enabled, your Action logs will include these specific markers: Description ##[debug]Resolved Keys: Shows the actual string used to find existing caches. ##[debug]Cache service version: Identifies the API version (e.g., v2).
While there isn't a single official tool named "debug-action-cache," debugging cache issues in GitHub Actions
is a common necessity for optimizing CI/CD pipelines. If you are facing "cache misses" or slow workflows, you can use several built-in methods to troubleshoot the actions/cache mechanism. 1. Enable Verbose Logging
The most effective way to see exactly why a cache is failing (e.g., version mismatches or path errors) is to enable diagnostic logging. This will show detailed logs of the download and upload process for your cached files. Step Debugging : Go to your repository Secrets and variables and add a new secret or variable named ACTIONS_STEP_DEBUG with the value Runner Diagnostic Logging ACTIONS_RUNNER_DEBUG
to get system-level information about the runner environment. 2. Verify Your Cache Keys Cache misses often occur because the generated by hashFiles() doesn't match what was previously saved.
step before your cache step to verify the files being hashed exist and have the expected content. Immutable Keys
: Remember that GitHub caches are immutable; once a key is saved, it cannot be updated. You must change the key (e.g., incrementing a version number like ) to "bust" the cache. 3. Use the Management UI
You can inspect the state of your caches directly in the GitHub web interface to see their size, creation date, and last access. Navigate to your repository on GitHub. In the left sidebar, click under the "Management" section.
Here, you can manually delete old or corrupted caches to force a fresh rebuild. 4. Interactive Debugging with tmate
If the cache is restoring files but they aren't where you expect them, use action-tmate to log into the runner via SSH while the job is active.
View cache usage in your Action workflows - GitHub Changelog
You can use this report to document findings after debugging cache misses, corruption, or restore failures.
The debug-action-cache technique is not about memorizing YAML syntax. It is about visibility. The silent restore, the missing package, the 10-minute delay—all of these yield to the developer willing to flip the debug switch.
Final checklist for your next cache emergency:
The next time your CI pipeline slows to a crawl, don't just add npm install again. Become the engineer who says, "I'll run it with debug-action-cache enabled—I’ll see exactly what’s happening under the hood."
That is the difference between guessing and knowing. Happy debugging.
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