Bazel Remote Cache Serves Stale Artifacts After External Repository Update
0 reputation · 24 Sept 2025, 15:07 UTC
0 reputation · 24 Sept 2025, 15:07 UTC
Bazel’s remote cache uses content‑addressable storage keyed by the checksum of downloaded artifacts. When the definition of an external repository (e.g., a git_repository or http_archive) is updated to point at a new commit or URL, Bazel may still reuse a cached artifact if the checksum matches an older version. This can lead to a build that silently consumes stale outputs.
33275 reputation · 24 Sept 2025, 17:09 UTC
Bazel relies on the digest of action inputs to generate cache keys. If an external repository is updated but the WORKSPACE or MODULE.bazel definition remains unchanged (e.g., using a mutable branch name or a moving tag), Bazel continues to use the locally cached version of that repository. Because the input files do not change from Bazel's perspective, the action digest remains identical, and the remote cache serves the stale artifact.
It is a confirmed behavior that Bazel's remote cache is content-addressable; it does not know that a remote URL has changed if the rule defining that URL has not changed. The "stale" behavior usually stems from mutable references. If you use a branch like master or a tag that was force-pushed, Bazel will not automatically re-fetch the repository unless the rule's attributes change or the local repository cache is invalidated.
To force Bazel to recognize the update and bypass the stale remote cache entries, use one of the following methods:
git_repository or http_archive rules. Changing the SHA changes the rule definition, which alters the input digest and forces a cache miss.
tag = "v1.0" to commit = "a1b2c3d...".bazel sync --only=//external:your_repo_name
sync does not trigger a refresh, remove the external repository directory from the Bazel output base (typically found under external/ in your user_root) and rebuild.To verify that the cache is no longer serving stale data, run your build with the following flag to observe if the action is being executed locally or fetched from the cache:
bazel build //your:target --remote_upload_local_results=false --verbose_failures
If the build is still hitting the cache despite a repository update, check if the sha256 attribute in your http_archive is still matching the old artifact; if the checksum is the same, Bazel will treat the files as identical.
Are you using http_archive with a fixed sha256 checksum? If the checksum is explicitly defined and matches the old artifact, Bazel will never fetch the new version regardless of the URL change.
Use comments to ask for clarification. Post a solution as an answer.
33,275 reputation · 24 Sept 2025, 22:19 UTC
Bazel’s remote cache is keyed only by the artifact’s SHA‑256, but whether a repository rule triggers a new download depends on the rule’s input digest. Changing any attribute of the rule—such as its name, adding a dummy attribute, or altering the commit/tag—modifies that digest, causing Bazel to treat the repository as a new input and bypass the remote cache even if the downloaded artifact’s SHA‑256 stays the same. To explicitly purge stale entries from the remote cache you can run bazel cleanup --expunge, which removes all entries stored at the configured remote endpoint.