OpenSSL verification error 19 (X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) means the chain the client received ends in a root certificate that is signed by itself and is not in the client's trust store. Public CAs also have self-signed roots, but clients already trust those. So the message almost always means a private or unknown root is in the path.
You will see it in many forms:
npm ERR! code SELF_SIGNED_CERT_IN_CHAIN
npm ERR! request to https://registry.npmjs.org/express failed, reason: self signed certificate in certificate chain
curl: (60) SSL certificate problem: self-signed certificate in certificate chain
fatal: unable to access '...': SSL certificate problem: self signed certificate in certificate chain
Do not confuse it with error 18, plain self-signed certificate, where the server's own leaf certificate is self-signed. That is usually a dev server. The chain variant points to something re-signing traffic on the way.
Who signed it?
Look at the issuers in the chain the failing machine actually receives:
openssl s_client -connect registry.npmjs.org:443 -servername registry.npmjs.org -showcerts </dev/null 2>/dev/null \
| grep -E "^ *[0-9] s:|^ *i:|Verify return code"
Compare with a machine on another network, such as a phone hotspot. If the issuer here is your employer, a security vendor or "localhost," the cause is on your path. Common sources:
- Corporate TLS inspection proxy. The proxy decrypts HTTPS, then re-signs it with a company root. Employees' browsers trust it because IT installed the root in the operating system store. Command-line tools often use a different store and do not.
- Antivirus or endpoint "HTTPS scanning" on a laptop does the same locally.
- A private CA used by an internal registry, Git server or API.
- A development server using a self-signed or mkcert-style certificate.
- A hotel, airport or school network with a captive proxy.
Fix: trust the right root, in the right tool
Get the root certificate as a PEM file from your IT team or export it from the OS store. Then point each tool at it. Each tool has its own setting:
export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/corp-root.pem
npm config set cafile /etc/ssl/certs/corp-root.pem
git config --global http.sslCAInfo /etc/ssl/certs/corp-root.pem
curl --cacert /etc/ssl/certs/corp-root.pem https://example.com/
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/corp-bundle.pem
pip config set global.cert /etc/ssl/certs/corp-bundle.pem
sudo cp corp-root.pem /usr/local/share/ca-certificates/corp-root.crt
sudo update-ca-certificates
On RHEL-family systems copy the file to /etc/pki/ca-trust/source/anchors/ and run sudo update-ca-trust. Java keeps its own store; see PKIX path building failed. Docker builds need the root copied into the image too, or the build step that runs npm install fails while your laptop works.
If you run the server and see this from your own client
Your own site presents a self-signed or private-CA certificate that clients do not trust. Choose one:
- Public service: get a publicly trusted certificate. Free CAs such as Let's Encrypt work; see renewal failures and automation.
- Internal service: distribute your CA root to every client through configuration management, and issue server certificates from that CA rather than using bare self-signed ones.
- Local development: use a local CA tool such as
mkcert, which installs a development root into your own trust stores.
Also check whether a CDN or load balancer is the party presenting an unexpected certificate; the CDN डिटेक्टर shows what sits in front.
Confirm the fix
curl -sS -o /dev/null -w "%{http_code} %{ssl_verify_result}\n" https://registry.npmjs.org/
ssl_verify_result of 0 means verification succeeded. Run openssl s_client again for Verify return code: 0 (ok), and for a server you own, check it with the SSL Chain Debugger.
अगले कदम
- See the sibling error unable to get local issuer certificate.
- Learn what each OpenSSL code means in verify return codes.
- Read curl error 60 for curl-specific flags.
- Review SSL certificate types explained.
सामान्य प्रश्न
Why does it work in my browser but not npm?
Your browser uses the operating system store, where IT installed the proxy's root. npm and Node use their own bundled roots, so they must be told about the extra root.
Is a self-signed certificate insecure by itself?
The encryption is fine; the problem is authentication. Clients cannot know the certificate really belongs to your server unless they were given it in advance through a trust store.
Should I disable SSL verification in CI?
No. Add the root certificate to the CI image or runner instead. Disabling checks leaves every dependency download open to tampering.
Why did it begin after I joined a VPN?
Many VPN and secure web gateway products inspect TLS. Check the issuer with openssl before and after connecting.
Get notified when this fix updates
Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.
यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.