1.1.11 bazel fetch
recommendedbazel fetch is the operator's preflight command for external dependencies. Bazel normally fetches external repos on demand while a build is already in progress. Running fetch first pulls that network-dependent setup forward, so the next build, test, or run can focus on your targets instead of discovering missing repos mid-flight1,2.
What fetch Does
External repos are not materialized on disk until Bazel needs them2. bazel fetch asks Bazel to do that repository work without building the requested targets themselves1,3.
bazel fetch //app:server
bazel fetch //...
bazel fetch --repo @rules_java
The first form prefetches everything needed for one target's transitive dependency graph. //... broadens that to the whole workspace. --repo @name is narrower still: fetch one external repo when you already know which dependency is the problem1,3. With Bzlmod enabled, bare bazel fetch is also valid for fetching all external dependencies in the workspace1.
If you need to inspect what was materialized, fetched repos live under the output base's external/ directory under their canonical repository names2. That is repository setup state, not a compiled output in bazel-bin.
Why operators run it explicitly
Operators run fetch to separate failure modes. A normal bazel test //... can spend time resolving repos, loading packages, analyzing targets, and only then tell you that a download failed. A fetch step makes dependency or network issues fail earlier and more clearly1,3.
bazel fetch //...
bazel test --nofetch //...
That pattern is useful in CI, where "the registry was unreachable" should be easy to distinguish from "the code does not compile." It is also the simplest preparation for offline work: prefetch while online, then run later commands with --nofetch so Bazel must use what is already available locally1,3. When 1.1.10 Common Error Messages surfaces no such package '@foo//', fetch is often the quickest way to isolate whether the problem is external dependency setup before you spend time on the rest of the build.
bazel fetch is only the first layer of offline strategy. Repository cache sharing, vendoring, mirrors, and full air-gapped setups belong later in 3.1.9 Offline / Air-Gapped Builds and 6.7.2 Operating Bazel Builds in Air-Gapped Environments3.
Pair it with --nofetch
By default, Bazel is willing to fetch new external dependencies during a build1,2. If you want the build to prove that every required external repository is already available, make that boundary explicit with --nofetch (equivalently --fetch=false)1,3. This flag blocks missing external-repository fetches. It does not disable other network users such as a remote cache, Build Event Service, or the test program itself.
Once you do that, the contract becomes simple: if a repo was already fetched or is present in the repository cache, Bazel uses it. If a required non-local repo is missing, the command fails instead of silently downloading it2,3. That is what turns fetch from "optional speed-up" into a real preflight step.
There are two times you usually need to fetch again: before the first build and after you add or change external dependencies1. In day-to-day Bzlmod work that usually means "after MODULE.bazel or related dependency setup changed," not after every source edit.
The cache you warm is the repository cache
bazel fetch mostly warms the repository cache: Bazel's shared store of downloaded external files1. That cache is separate from the workspace-local build outputs and action metadata discussed in 1.1.6 bazel clean, and the full taxonomy comes later in 2.4.2 Where Bazel Caches Things1.
Prefetching a dependency avoids a later network trip to materialize those repos. The next build still has to load, analyze, and execute your target graph as usual.
If you want to modify a dependency or check it into the repo, use bazel vendor.
fetch prewarms Bazel's dependency machinery. Vendoring changes how the
dependency is sourced and managed3.
If older docs in your team mention bazel sync, treat that as legacy WORKSPACE-era advice. Under Bzlmod, fetch absorbed most of that operator-facing job, and --force is the explicit way to refetch when the repo definition itself did not change4,5. The deeper mechanics of unwanted repo downloads show up later in 3.1.5 Eager Fetch Anti-pattern.
Use bazel fetch when you want external dependency resolution to be a separate, explicit step that prepares repositories without building your targets. Pair it with --nofetch when you want CI or offline workflows to fail fast on missing dependency state instead of hiding network work inside a normal build.
Check your understanding · 2 questions
1.True or false: bazel fetch behavior.
Choose True or False for each sentence
2.Which command is the better fit when dependencies must be editable or checked into the source tree?
Select one answer
Footnotes
-
Build programs with Bazel —
bazel fetchforms,--fetch=false, barebazel fetchwith Bzlmod, repository cache, and offline prefetch guidance ↩1 ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 -
External dependencies overview — external repos are fetched on demand,
fetchmakes them available locally,--nofetchuses cached copies only, and fetched repos live underoutput_base/external/↩1 ↩2 ↩3 ↩4 ↩5 -
Frequently asked questions —
--repo, target-pattern fetch,--nofetch, offline-build preparation, and whenbazel vendoris the better fit ↩1 ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 -
Bzlmod Migration Guide —
fetchvs legacysyncin the WORKSPACE-to-Bzlmod transition ↩ -
Repository Rules — when Bazel refetches repos and how
bazel fetch --force/--configureaffect repo-rule refresh ↩