Once a month, run a clean build on a runner with the public registry blocked and each tool in its offline mode. If it passes, your cache or vendor copy works. If it fails, you have found a hidden network dependency before an outage finds it for you. The drill takes about 20 minutes.
Why a drill and not a plan
A cache that has never been used in anger is a guess. Tools quietly fetch things you forgot about: a binary downloaded by an install script, a base image pulled by tag, a plugin resolved at build time. The only way to find them is to take the network away and watch.
The offline switch for each tool
Each package manager documents a way to avoid the network. The wording below follows the official references.
| Tool | Offline mechanism | Documented behaviour |
|---|---|---|
| npm | offline setting | Forces offline mode, no network requests during install |
| npm | prefer-offline setting | Skips staleness checks for cached data but still requests missing data |
| pip | no-index with find-links | Ignores the package index and looks only at the locations you give it |
| cargo | net.offline setting | Avoids the network and proceeds with locally cached data |
| Go | vendor mode | The go command will not use the network or the module cache |
| Go | GOPROXY set to off | Disallows downloading modules from any source |
The commands
Run each in a fresh checkout, on a runner or container that cannot reach the public registry.
# npm: fail if anything is missing from the cache
npm ci --offline
# pip: install only from a local wheelhouse
pip install --no-index --find-links ./wheelhouse -r requirements.txt
# cargo: use only what is already downloaded
CARGO_NET_OFFLINE=true cargo build --locked
# Go: build from the vendor directory
GOFLAGS=-mod=vendor go build ./...
If you want a Go build that fails on any download but still uses the module cache, set the proxy to off instead. See go mod vendor to keep building offline, pip wheelhouse for offline Python installs and cargo locked, frozen and offline.
The 20 minute routine
- Pick one representative service per ecosystem. Do not try every repository in one month.
- Block outbound traffic to the public registry. A container started with no network is a simple way to do this.
- Run the commands above and time them.
- Write down each failure: what it tried to reach and why.
- Fix the cheapest failure first, usually by adding a package to the wheelhouse or vendor directory, or by pointing a tool at the mirror.
- Record the result with a date. Auditors and customers like evidence that you rehearse, and this gives you some.
What failures usually mean
- A missing package means the cache was filled by a different lockfile than the one you built.
- A download in an install script means the dependency is doing more than installing files. Review it, since it matters for supply chain risk as well as for offline builds.
- A failed base image pull means the image was never copied into your own registry.
- A slow pass means the cache is cold on the runner, which affects your recovery time.
Pair the drill with the broader outage practice in package registry outage: keep building with a cache or mirror.
Try it yourself
Click through it at your own pace, or open it full screen.
Open the inventory and look for packages you did not know you depended on. Those are the ones most likely to fail an offline drill.
Where Safeguard fits
The drill tells you whether builds work offline. Safeguard's SBOM and dependency scanning tells you what those builds contain, so the vendor copy or wheelhouse you rely on is not an unexamined pile of packages. You can try a free scan at gold.safeguard.sh/scan.
Quick check
Does npm offline mode fetch missing packages?
No. Offline mode makes no network requests during install, so a missing package fails the install. Prefer-offline fetches what is missing.
How often should the drill run?
Monthly is a practical rhythm for most teams. Run it again after you change runners, mirrors or lockfile tooling.
Sources
Last reviewed: 19 October 2026.