3.1.7 Registry Immutability
recommendedBazel registries can be local directories or static HTTP servers, so pointing --registry at a repo-owned directory looks tempting at first.1 The catch is that Bazel treats registry metadata like published input, not like a live scratchpad: the registry copy of MODULE.bazel participates in external dependency resolution, and the Bazel server caches registry files in memory with the expectation that they do not change after publication.1,2,3 That assumption is harmless for append-only registries such as the BCR, but it becomes a real maintainer trap if you keep editing a local or in-repo registry after Bazel has already read it.3,4
Why registry edits are different from source edits
An index registry does more than point at source archives. It also carries the registry-side MODULE.bazel, source.json, and optional patches and overlays that Bazel uses while resolving and fetching a module version.1 The MODULE.bazel stored in the registry is the source of truth during external dependency resolution, not the MODULE.bazel sitting inside the source archive.2
That is why a registry entry behaves more like published package metadata than like a checkout you can safely tweak in place. If you need to experiment on a dependency, the normal workflow from 3.1.1 Bzlmod (MODULE.bazel) is to use an override, not to mutate an already-consumed registry version.5
The warm-server failure mode
The operational gotcha shows up as soon as the same Bazel server sees both the old and new registry contents. Even a file:/// registry clone may require bazel shutdown before every command while you iterate, because the Bazel server caches registry fetches in memory.3
That same behavior becomes much more painful in CI. In a large monorepo with workers that keep Bazel warm between jobs, an in-repo registry exposes it: a defective registry change may not be detected immediately because Bazel keeps reusing cached registry metadata, and recovery requires more than reverting the bad commit — the published version also has to change and the merge queue has to be reset.4 This is a different failure mode from mirror availability and downloader setup in 3.1.6 BCR Infrastructure. The bytes can be local and reachable, but Bazel is still intentionally trusting the previously fetched registry metadata.
common --registry=file://%workspace%/third_party/registry
That configuration is supported.1,4 It is just unsafe if the directory is treated like normal source code that contributors keep editing after Bazel has cached it.
Safer maintainer workflow
For local development, use a non-registry override first. local_path_override is the simplest option when you have a checkout on disk, and Bazel also supports archive- and Git-based non-registry overrides for other cases.5 Those overrides remove the module from registry-based version resolution, which is exactly what you want while the dependency is still moving.5
Once the dependency works, publish a new immutable registry version or contribute the change to BCR. If your organization really needs a private registry, treat it as append-only published metadata and use 3.1.8 Registry Structure & Custom Registries for the hosting mechanics. Do not use the registry itself as the iteration surface. That is what overrides are for.4,5
Check your understanding · 3 questions
1.A team keeps a local in-repo registry and edits it directly after publishing a version. What failure mode should they expect?
Select one answer
2.True or false about registry immutability:
Choose True or False for each sentence
3.Why does the registry copy of MODULE.bazel take precedence over the one inside the source archive during dependency resolution?
Select one answer
Footnotes
-
Bazel registries — local-directory and static-HTTP registries, plus the registry-side
MODULE.bazel,source.json, patches, and overlays ↩1 ↩2 ↩3 ↩4 -
Frequently asked questions — the registry
MODULE.bazelis the source of truth for module version during external dependency resolution ↩1 ↩2 -
Adopting Bazel's new package manager — local registry clones are cached by the Bazel server, so testing registry edits often requires
bazel shutdown↩1 ↩2 ↩3 ↩4 -
A Product-First Approach to Growing BCR - Jordan Mele, Canva — immutability requirement, in-memory registry cache, in-repo registry failure mode, and override-first recommendation ↩1 ↩2 ↩3 ↩4 ↩5
-
Bazel modules — non-registry overrides such as
local_path_override,archive_override, andgit_override↩1 ↩2 ↩3 ↩4 ↩5