To keep building when a package registry is down or a package vanishes, put a caching proxy or internal mirror between your builds and the public registry, install strictly from lockfiles, and keep the artifacts of your last good build. Test a build with the public network blocked so you know it works.
Three ways this goes wrong
- The registry is unavailable. Every clean build fails at install time.
- A package or version disappears. A maintainer removes it, or it is taken down for being malicious. npm's policy shows how this works: unpublishing is allowed under conditions, and an unpublished version number can never be reused.
- A version is hidden from resolution. Python's PEP 592 describes yanking, where installers should ignore yanked releases when a non-yanked version satisfies the request, and cargo yank removes a version from the index without deleting the crate. Your builds can change behavior without any change on your side.
Build the cache layer
A caching proxy. Run a proxy that stores every package your builds fetch. When the public registry is down, builds use the stored copy. When a package is removed upstream, your copy remains until you choose to drop it.
Or an internal mirror. A mirror holds a curated set of packages. It gives more control, for example blocking a version after an incident, at the price of more upkeep.
Whichever you pick, decide who owns it, where it runs, and how it is backed up. A cache in the same failing region as your builds solves little. Check that credentials to the cache work from your recovery region too, as the single region dependency audit suggests.
Use lockfiles correctly
A lockfile records exact versions so builds are repeatable. With npm, npm ci installs from the lockfile, deletes existing node_modules first, and errors if the lockfile and package.json disagree. Use that kind of strict mode in CI so a registry hiccup cannot silently resolve different versions. Cargo's yank behavior shows the benefit too: existing lockfiles are not affected, so a project whose lockfile already pins a yanked version keeps building.
For background, read what a lockfile is and why to commit it.
Keep what you built
Store the output of each release build, such as images and bundles, in a registry you control. When the pipeline is stuck, the fastest recovery is redeploying a previous artifact, and that does not need the package registry at all.
Consider vendoring only for the packages that are critical and rarely change. The trade-offs are in should you vendor dependencies into your repo.
Test it
Once a quarter, run a clean build with outbound access to the public registry blocked. Anything that fails is a hidden dependency: a postinstall script that downloads a binary, a base image pulled from a public registry, a build tool fetched on the fly. Fix them one at a time.
Decide the policy for removals
When a dependency is removed upstream, who decides whether to keep your cached copy? For a malicious package, remove it from the cache and investigate. For a package pulled over a licensing dispute, a legal view may be needed. Write the rule down.
Quick check
Does a lockfile alone protect us from a registry outage?
No. It makes versions repeatable, but the files still have to come from somewhere. You need a cache, mirror or stored artifacts.
What is the cheapest first step?
Block outbound access to the public registry in a test build and see what fails. Then add a caching proxy.
Sources
- npm Docs: Unpublish policy
- npm Docs: npm ci
- PEP 592: Adding yank support to the Simple API
- Cargo Book: cargo yank
Last reviewed: 19 October 2026.