Where the Request Failed
npm rejected the HTTPS certificate because the registry or proxy certificate has been revoked and is no longer trusted.
npm is telling you the request failed before it got a clean response back. Treat the connection path and the failing environment as the first suspects, not the package or image name.
Fix certificate trust and TLS
Start by proving the failing machine can reach the right host cleanly. Until DNS, routing, proxy, and trust look sane in that exact environment, retrying the install or pull is mostly noise.
Confirm which registry host npm is calling:npm config get registry
Check system time and timezone (NTP). If it's wrong, fix it and retry.
Check for proxy settings:npm config get proxy and npm config get https-proxy
Check TLS config:npm config get strict-ssl and npm config get cafile
Run a quick registry check:npm ping
If this only fails on your office/VPN but works on a hotspot, treat it as corporate TLS interception until proven otherwise.
Proper fix:trust the CA that is signing the certificate chain.
If you are behind a corporate TLS proxy, export the corporate root CA and configure npm:npm config set cafile /path/to/corp-ca.pem
In CI, prefer NODE_EXTRA_CA_CERTS=/path/to/corp-ca.pem so Node trusts the internal CA without changing global npm config.
If you control the registry/proxy, ensure it serves the full certificate chain (leaf + intermediates).
Inspect the served chain:openssl s_client -showcerts -connect <host>:443 -servername <host> </dev/null
Temporary diagnostics only:if you must confirm a trust issue, run npm --strict-ssl=false <command> once, then restore validation immediately.
Do not leave strict-ssl=false or NODE_TLS_REJECT_UNAUTHORIZED=0 in CI, shell profiles, or checked-in config. They disable certificate validation and increase MITM risk.
If you changed npm config for a one-off test, revert it immediately:npm config set strict-ssl true and unset NODE_TLS_REJECT_UNAUTHORIZED
Retry with npm --verbose and keep the full output for troubleshooting.
Manual certificate validation
If the main log is noisy or truncated, these checks let you isolate the failing layer directly and confirm whether you are dealing with configuration, access, trust, or local environment state.
Confirm the failing host matches your registry:npm config get registry
If you control the registry/proxy, ensure it serves the full certificate chain (leaf + intermediates).
Inspect the served chain:openssl s_client -showcerts -connect <host>:443 -servername <host> </dev/null
If curl works but npm fails, the issue is usually Node's CA trust (fix with NODE_EXTRA_CA_CERTS / cafile).
If you need a short diagnostic retry with SSL disabled, restore validation immediately afterward.
Why It Happens
Usually this comes down to a corporate proxy/VPN is intercepting HTTPS and presenting a certificate signed by an internal CA that Node does not trust, your registry (or proxy registry) is serving an incomplete chain (missing intermediate CA certificates), system time is incorrect, which can make otherwise valid certificates fail validation, or node/npm is using a CA trust store that does not include the required issuer certificates.
Prove the Failing Environment Can Reach It
Run npm ping (same network, same registry) and confirm it succeeds, and re-run the original command and confirm the TLS error no longer appears.
How npm verifies TLS certificates
npm uses Node.js for HTTPS. Certificate validation happens in Node's TLS stack. The server must provide a valid chain to a trusted root CA, and the certificate must match the hostname. Proxies that intercept TLS must be trusted by adding their root CA to the client trust store (or configuring cafile).
Examples
npm ERR! code CERT_REVOKED Prevent Repeat Connectivity Failures
To prevent this, bake your corporate root CA into CI runner images (or distribute via configuration management), use a registry or proxy that serves a complete, valid certificate chain, and keep Node.js and npm updated so you get current CA bundles and TLS defaults.
Docs and source code
github.com/npm/cli/blob/417daa72b09c5129e7390cd12743ef31bf3ddb83/lib/utils/ping.js
This is the registry request path where npm talks to the network. DNS/TLS errors like this code are raised by Node/OS during this request. - GitHub
// used by the ping and doctor commands
const npmFetch = require('npm-registry-fetch')
module.exports = async (flatOptions) => {
const res = await npmFetch('/-/ping', { ...flatOptions, cache: false })
return res.json().catch(() => ({}))
}