Check three things: the registry's status page, a plain request from a machine outside your CI network, and the exact error in the log. If the status page is red and your outside request fails, it is the registry. If the outside request works and CI does not, look at your runners, proxy and DNS.
Minute 0 to 2: read the error, do not guess
Open the failing log and copy the first error line, not the last. Note the status code if there is one. A code means a server answered, so the network works. A timeout, a connection reset or a name resolution error means the request never completed. Those two families point in different directions. The meanings of common codes are in registry errors in CI.
Minute 2 to 4: the status page
Most public registries publish a status page with incident updates, and many offer email or text subscriptions. The Python infrastructure status page, for example, offers subscriptions for incidents. Look at the page for the registry you use. A listed incident explains a lot, but an empty page does not rule out a problem. Status pages lag, and they may not cover your region.
Subscribe to the pages of registries you depend on before you need them. It is a two minute task for the person who owns your mirror.
Minute 4 to 7: test from two places
Run the same request from your CI runner and from a laptop or another network. Use a plain HTTP client so you take the package manager out of the picture.
# from the runner and from a machine outside your CI network
curl -sS -o /dev/null -w "%{http_code} %{time_total}s\n" https://registry.example.org/some-package
Read the result as a small table.
| Runner result | Outside result | Likely cause |
|---|---|---|
| Fails | Fails | The registry or its CDN |
| Fails | Works | Your runners, proxy, DNS or egress rules |
| Works | Works | Intermittent, a rate limit, or a package specific problem |
| 429 | Works | Your egress address is limited, see the shared IP post |
Replace the example host with your real registry. If you use a mirror, test both the mirror and the public registry, because that separates mirror trouble from upstream trouble.
Minute 7 to 10: narrow it down
- Proxy variables. Check whether the runner sets HTTP proxy variables that changed recently.
- DNS. Resolve the hostname from the runner. A failure here is yours.
- Certificates. A TLS error after a runner image update often means a missing certificate authority bundle.
- Credentials. A 401 only on one pipeline points at a token, not an outage.
- Recent changes. Did a runner image, firewall rule or mirror setting change today?
If everything points at a global problem, switch to your fallback plan from package registry outage: keep building with a cache or mirror. If you are unsure whether it is an outage or an attack, the general method is in outage or attack: how to tell in the first hour.
What to write down
Record the time, the first error line, both curl results and what you decided. It takes a minute and makes the postmortem easy. It also helps you tune your retry and timeout settings. See how long npm, pip and cargo retry a dead registry.
Where Safeguard fits
During an incident you also need to know whether any build used a version you now doubt. Safeguard's SBOM and dependency scanning gives you that inventory, so the question is answered from records and not memory.
Quick check
If the status page is green, is the registry fine?
Not necessarily. Status pages can lag or miss regional problems. Trust your own request from a second network.
Why test with curl and not the package manager?
A plain request removes the tool, its cache and its configuration from the picture, so you see whether the network path works.
Sources
Last reviewed: 19 October 2026.