Safeguard
Supply Chain•

What is build cache poisoning and how do you recover?

Build cache poisoning plants a bad output where later builds will reuse it. Learn how it happens in shared caches, how to spot it and what to clear.

Safeguard Security Team
4 min read

Build cache poisoning means a wrong or malicious output gets stored in a shared build cache, so later builds reuse it instead of rebuilding. Recovery usually means cutting off write access, clearing the affected cache, and rebuilding from source on a trusted machine.

Definition

Build tools such as Bazel, Gradle, Nx and Turborepo compute a hash of a task's inputs and look up the result. If the hash matches a stored entry, the tool restores the stored output. That is the speedup. It is also the trust boundary: the tool trusts that whoever stored the entry produced it honestly and correctly.

Poisoning has two flavors.

  • Accidental: the task read something its hash did not cover, so a wrong output was stored under the right key.
  • Deliberate: someone with write access stored a crafted output under a key that real builds will compute.

How accidental poisoning happens

Bazel's documentation names several causes. An input file modified during a build can lead to invalid results uploaded to the remote cache. Environment variables leaking into an action change its definition. Tools outside the workspace are not tracked, so two users with different compilers at the same path can share cache hits despite different outputs.

Turborepo documents a similar failure with environment variables. A build made with a preview value for an API address was restored from cache for a production build, because the variable was available at runtime but not in the task hash.

How deliberate poisoning happens

The common route is write access that is too broad: laptops, fork pull requests or a leaked cache token can all write. Anyone who can write a correct looking entry for a key that other builds will compute controls what those builds restore.

Signs to look for

  • A cached artifact differs from a clean local rebuild of the same commit.
  • Hits for tasks that should have missed after a dependency or configuration change.
  • New cache writes from identities that should be read only.

Recovery steps

  1. Revoke or rotate write credentials and tokens.
  2. Restrict writes to trusted CI before turning anything back on.
  3. Clear the shared cache. Bazel's docs state that content cannot be mapped to a specific build, so clear the whole cache or all entries from the suspect window.
  4. Clear local caches on developer machines and CI runners too, as covered in the post on purging CI caches after a compromise.
  5. Rebuild release artifacts from source on a clean machine and compare against anything already shipped.
  6. Fix the underlying cause: declare the missing inputs, enable strict environment handling, tighten write rules.

Prevention in one line

Make the write path narrow, make the hash complete, and make rebuilding from source routine, so you notice when a cache and a clean build disagree.

Where Safeguard fits

Safeguard can inventory the dependencies your repository declares through SBOM and dependency scanning, and reachability analysis helps you decide which findings matter first. You can try a free scan on a repository to see what it finds. Check coverage for your specific build files before relying on it.

Try it yourself

Open the demo and watch how a monitored inventory surfaces a change after the fact, which is the habit that helps you notice a bad artifact.

Click through it at your own pace, or open it full screen.

Quick check

Can a read only cache client be poisoned?

It can receive a poisoned entry written by someone else, but it cannot add one itself.

Is clearing the cache enough after deliberate poisoning?

Not alone. Also rotate the credentials that allowed the write and rebuild anything shipped during the window.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.