Error message
npm error code DEPTH_ZERO_SELF_SIGNED_CERT
Also printed as
- npm ERR! code DEPTH_ZERO_SELF_SIGNED_CERT
npm 10 and later print "npm error code DEPTH_ZERO_SELF_SIGNED_CERT", npm 9 and older "npm ERR! code DEPTH_ZERO_SELF_SIGNED_CERT". The reason line reads "self-signed certificate", with the --use-system-ca hint on recent Node.js versions.
npm (Node.js) — registry request over HTTPS
What it means
The registry npm connected to presented a single self-signed certificate that Node.js does not trust. There is no CA chain at all, so the only ways forward are to trust that exact certificate deliberately or to give the registry a CA-issued certificate. Typical for local or self-hosted registries started with a generated certificate.
Why it happens
A local or self-hosted registry with a generated certificate
commonVerdaccio, a Nexus or Artifactory trial, or a registry container started with a self-signed certificate.
An appliance or proxy with its factory certificate
occasionalSome caching proxies and network appliances present a self-signed certificate until a proper one is installed.
A Kubernetes ingress answering with its default certificate
occasionalWhen the registry's host is not configured on the ingress, it serves a self-signed default certificate (for ingress-nginx: "Kubernetes Ingress Controller Fake Certificate").
How to fix it
- 1.
Trust exactly this certificate
Fetch the certificate, compare its SHA-256 fingerprint with the one shown on the registry host, then add it with NODE_EXTRA_CA_CERTS (or npm's cafile).
bash # Save the registry's certificate, check its fingerprint, and trust exactly this file openssl s_client -connect registry.example.com:443 -servername registry.example.com </dev/null 2>/dev/null \ | openssl x509 -out registry.pem openssl x509 -in registry.pem -noout -fingerprint -sha256 NODE_EXTRA_CA_CERTS=$PWD/registry.pem npm install - 2.
Limit the private registry to your scope
Routing only your organisation's scope to the private registry keeps all public packages on registry.npmjs.org, so a certificate problem on the private host cannot affect them.
ini ; .npmrc — only @acme packages come from the private registry; the rest from npmjs @acme:registry=https://registry.example.com/ - 3.
Give the registry a CA-issued certificate
A certificate from a public CA (ACME) or from the company CA your machines already trust removes the need for per-certificate exceptions.
bash # Give the registry a certificate from a CA your machines trust (public ACME or company CA) sudo certbot certonly --standalone -d registry.example.com