Bazel remote caching: inconsistent action hashes with identical inputs
0 reputation · 23 Jun 2025, 15:36 UTC
0 reputation · 23 Jun 2025, 15:36 UTC
Bazel utilizes a content-addressable storage (CAS) system to ensure that action outputs are retrieved based on a hash of their inputs. In a remote caching environment, achieving consistent cache hits across different CI runners and developer workstations is critical for build performance.
There is a design uncertainty regarding how Bazel handles absolute paths embedded within generated files or toolchain configurations. If a build rule is not strictly hermetic, the resulting action hash may vary between environments despite the source code remaining unchanged, leading to unexpected cache misses.
--remote_download_outputs=toplevel flag affect the visibility of these cache misses during the build summary analysis?Bazel detects and neutralizes non-deterministic inputs by computing a unique action cache key derived from the command line, the content and paths of input files, declared environment variables, the configuration hash (build flags), and action-specific salts. Any variance in these components—even if the source code is identical—results in a different hash and a cache miss.
Hash divergence typically occurs when builds are not strictly hermetic. The most common culprits are differences in host tool versions (e.g., different JDK or Python versions), varying PATH variables, locale settings, or absolute paths leaked into generated files. These environmental differences alter the action's command line or environment manifest, triggering a new hash.
--host_force_python=PY3 or specifying a fixed JDK via --host_javabase.BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 to prevent the auto-detection of varying host C++ compilers.--verbose_failures to identify the action ID of the miss. On both the CI runner and local workstation, execute:
bazel dump --action_cache <action-id>
Compare the Command line, Input manifest, and Environment sections to find the specific differing string..bazelrc using build --action_env=VAR=value to ensure consistency.The --remote_download_outputs=toplevel flag instructs Bazel to download only the final outputs of the requested targets. While intermediate actions may still experience cache misses and be executed locally, these misses are often obscured in the high-level build summary. Because the intermediate outputs are not downloaded to the local machine, the visibility of the "miss" is reduced, making it harder to diagnose nondeterminism without inspecting detailed execution logs.
If hashes remain inconsistent after normalizing toolchains and environment variables, please provide the output of bazel dump --action_cache <action-id> from both environments to determine if the divergence is rooted in the input manifest or the command line.
Use comments to ask for clarification. Post a solution as an answer.
4,460 reputation · 23 Jun 2025, 15:51 UTC
Bazel computes the action key from the execution root‑relative paths of declared inputs, the command line, the environment, and the configuration hash. The workspace root’s absolute path is not part of the key; therefore, two machines with different checkout directories will still produce the same hash as long as the action does not explicitly embed $(pwd) or a hard‑coded absolute string. If a rule leaks such a path into its output (e.g., via a genrule that copies a file with $(pwd)), the output differs and the hash changes, causing a cache miss even though the source is unchanged.