3.1.6 BCR Infrastructure

recommended

Bzlmod in 3.1.1 Bzlmod (MODULE.bazel) makes external dependencies feel simple, but production reliability depends on infrastructure below that friendly bazel_dep() surface. The Bazel Central Registry is only the metadata layer: Bazel asks a registry for module files and fetch instructions, then downloads source archives from whatever URLs those registry entries point at. If either layer fails, the build fails for a different reason, and the mitigation is different too.1,2

BCR is metadata and fetch policy, not artifact storage
Registry files tell Bazel where to download. Outages and mitigations can occur in either layer.
BAZEL BUILD
Resolves the module graph for this workspace
Fetches small registry files first
bazel_dep() → registry lookup
REGISTRY METADATA
Serves MODULE.bazel and source.json per version
Index tree or static HTTP, not the tarball
bcr.bazel.build · custom --registry
SOURCE ARCHIVE
Tar or zip bytes from URLs listed in source.json
Often GitHub, release CDN, or mirror host
SHA-256 must match declared integrity
different failure surfaces
REGISTRY OUTAGE
Module resolution fails before any source archive downloads
Metadata layer only
Point --registry at a mirror or raw tree (for example GitHub raw), or serve a replicated registry endpoint until metadata is reachable again.
ARCHIVE OUTAGE
Fetches or checksums fail even when registry files load fine
Source bytes layer only
Prefer static release artifacts. Use mirror_urls, bazel_registry.json mirrors, mirror.bazel.build, internal blobs, --downloader_config, or --module_mirrors.
A committed MODULE.bazel.lock plus a warm --repository_cache avoids live network only for metadata and archives already fetched once. Cold machines still need both layers.

What the registry actually serves

An index registry is just a directory tree or static HTTP server. For each module version it serves the registry copy of MODULE.bazel, a source.json file describing how to fetch the source, and optional patches or overlay files.1 The source archive itself usually lives somewhere else.

That separation matters operationally. A healthy bcr.bazel.build endpoint does not guarantee that the archive URL in source.json is healthy, stable, or even still available.1,2 Conversely, mirroring source archives does not help if Bazel cannot fetch registry files in the first place. The full registry layout and custom hosting model are covered in 3.1.8 Registry Structure & Custom Registries.

Registry outages and archive outages are different failures

When the hosted BCR endpoint is unavailable, module resolution can fail before Bazel even starts downloading dependency sources. Hosted-registry incidents have a different recovery shape from archive outages: users can often get unstuck by pointing --registry at a mirrored or raw copy of bazelbuild/bazel-central-registry, because Bazel only needs static registry files at that stage.3,1

common --registry=https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main/

Archive failures are a separate problem. Many module entries still point at upstream release artifacts or GitHub archive endpoints. Archive checksum churn is the cautionary story here: GitHub-generated /archive/refs/... tarballs are not a stable byte-level API, so a server-side Git upgrade can change the SHA-256 of the downloaded archive even when the extracted source tree is effectively the same.2 That is why "it builds from BCR" is not the same thing as "it is insulated from upstream archive churn."

The safe default is to prefer static release artifacts that maintainers publish intentionally, then mirror those artifacts so Bazel has a second place to fetch from.2 mirror.bazel.build is the ecosystem's shared version of that pattern. Large organizations usually add their own mirror in front of the same artifacts.2

The knobs maintainers actually use

There are several layers where you can add resilience:

  • Registry authors can declare registry-wide source mirrors in bazel_registry.json. Bazel prefixes the original source URL with each mirror base and tries those before the original URL.1
  • Individual module versions can add mirror_urls in source.json as explicit backups for a single archive.1
  • Consumers can replace the default registry entirely with repeated --registry flags, for example to prefer an internal registry or a mirrored BCR endpoint.1
  • Consumers can steer archive downloads with --downloader_config or --module_mirrors, which is especially useful in CI or during temporary infrastructure incidents.4

The local-registry-chain snippet isolates the consumer-side registry knob: its assertion script runs bazel mod graph and bazel build with a file:// registry first and https://bcr.bazel.build configured second. The demo module exists only in the local registry, while the command keeps the public registry as an explicit fallback for other modules.

One practical pattern is to keep a small downloader config ready so Bazel can rewrite known URLs toward internal storage during an outage or controlled migration:3

# .bazel_downloader.cfg
rewrite mirror.bazel.build/(.*) storage.googleapis.com/example_bucket/$1

These knobs provide alternate routes while Bazel is still fetching dependencies. They are not the offline-build mechanism: prefetching, repository-cache reuse, and vendoring belong to 3.1.9 Offline / Air-Gapped Builds, while CI air-gap operations belong to 6.7.2 Operating Bazel Builds in Air-Gapped Environments.4

Keep the concerns separated

It helps to keep three distinct questions separate:

  1. Can Bazel reach registry metadata at all?
  2. Are the source archives behind those metadata entries byte-stable and mirrored?
  3. Do we trust the artifact we downloaded to match the reviewed source?

This article is about the first two. The immutability rules for registry contents themselves are the next topic in 3.1.7 Registry Immutability. The trust/provenance side is improving through BCR attestation work, but that is a security story more than an availability story. The deeper model lives in 6.7.6 Build Provenance and Attestations.5

key takeaway

Treat BCR as dependency metadata plus fetch policy, not as artifact storage. Registry failover keeps metadata reachable. Archive mirrors and downloader policy keep source bytes reachable. Lockfiles, prefetching, and vendoring are the separate offline layer in 3.1.9 Offline / Air-Gapped Builds.

extra

Provenance is getting better, but it solves a different problem

Recent BCR publishing work can attach provenance attestations to module releases, which helps answer "was this release artifact built from the source I reviewed?"5 That does not remove the need for mirrors, downloader policy, or alternate registry endpoints. Availability and authenticity reinforce each other, but they fail in different ways.

Check your understanding · 3 questions

1.BCR's hosted endpoint at bcr.bazel.build is unreachable, but the underlying bazelbuild/bazel-central-registry repository on GitHub is fine. Why does pointing --registry=https://raw.githubusercontent.com/bazelbuild/bazel-central-registry/main/ reliably keep builds going?

Select one answer

2.True or false about BCR infrastructure and archive stability:

Choose True or False for each sentence

A module published to BCR guarantees that its source archive URL will always return identical bytes.
Registry outages and source archive outages are distinct failure modes requiring different mitigations.
mirror.bazel.build provides an ecosystem-shared mirror of source archives as a backup fetch location.

3.Match each resilience knob to the failure mode it best mitigates:

Drag each answer onto the matching prompt, or click an answer and then click a prompt

Answers
mirror_urls in a module's source.json
--registry flag
--downloader_config / --module_mirrors
Committed MODULE.bazel.lock + warm --repository_cache
0 of 3 answered

Footnotes

  1. Bazel registries — index registry layout, bazel_registry.json mirrors, source.json, BCR role, and --registry 1 2 3 4 5 6 7

  2. How GitHub's upgrade broke Bazel builds — unstable GitHub archive checksums, mirror.bazel.build, and why BCR metadata does not by itself solve archive stability 1 2 3 4 5

  3. December 2025 Bazel Central Registry Outage — concrete hosted-BCR incident, raw GitHub registry fallback, and downloader-config workaround patterns 1 2

  4. Frequently asked questions--repository_cache, --downloader_config, --module_mirrors, and insulating builds from the Internet 1 2

  5. Securing Bazel's Module Registry — provenance attestations for BCR modules and their role in artifact trust 1 2