Error Knowledge Base NPM CERT_HAS_EXPIRED

npm ERR! code CERT_HAS_EXPIRED

npm rejected the registry HTTPS certificate because it is expired.

Affected versions: All supported npm versions.

What This Error Means

npm rejected the registry HTTPS certificate because it is expired.

How to Fix It

  1. Confirm which registry host npm is calling: npm config get registry.
  2. Check for proxy settings: npm config get proxy and npm config get https-proxy.
  3. Check TLS config: npm config get strict-ssl and npm config get cafile.
  4. Check system time (NTP) and retry.
  5. If you control the registry/proxy, renew/rotate the certificate and include intermediates.
  6. Quick confirmation (insecure, temporary): run once with npm --strict-ssl=false <command>. If it works, fix CA trust instead of leaving SSL checks disabled.
  7. Alternative temporary config toggle (insecure): npm config set strict-ssl false, retry once, then immediately revert: npm config set strict-ssl true.
  8. Alternative one-off (insecure): run once with NODE_TLS_REJECT_UNAUTHORIZED=0 (do not use in CI, remove afterward).
  9. Proper fix: trust the CA that is signing the certificate chain.
  10. 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.
  11. In CI, prefer NODE_EXTRA_CA_CERTS=/path/to/corp-ca.pem so Node trusts the internal CA without changing global npm config.
  12. Retry with npm --verbose and keep the full output for troubleshooting.

Why It Happens

  • System time is wrong (certificate validity checks fail immediately).
  • The registry/proxy certificate is actually expired.
  • A corporate TLS proxy is serving an outdated certificate chain.

How to Verify

  1. Run npm ping (same network, same registry) and confirm it succeeds.
  2. Re-run the original command and confirm the TLS error no longer appears.

Manual certificate validation

  1. Confirm the failing host matches your registry: npm config get registry.
  2. If you control the registry/proxy, ensure it serves the full certificate chain (leaf + intermediates).
  3. Inspect the served chain: openssl s_client -showcerts -connect <host>:443 -servername <host> </dev/null.
  4. Look at the leaf certificate Not After date and confirm it is not expired.

Common CLI Output

npm ERR! code CERT_HAS_EXPIRED

How npm verifies TLS certificates

  1. npm uses Node.js for HTTPS. Certificate validation happens in Node's TLS stack.
  2. Expired certificates are rejected during the TLS handshake before npm can fetch package metadata.

Prevention Tips

  • Keep build machines time-synced (NTP).
  • Monitor certificate expiry for registries and proxies.
  • Bake corporate root CAs into CI images when TLS interception is expected.

Where This Can Be Triggered

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(() => ({}))
}

Need help or found a mistake? Contact RepoFlow support for questions.

Join our mailing list