- npm
- Exact text checked with the real tool
UNABLE_TO_GET_ISSUER_CERT_LOCALLY
Also seen in: Node.js, yarn, pnpm, fetch (undici), axios
In one sentence
npm (Node.js) reached a CA certificate whose issuing root it does not have: usually a TLS-inspection proxy or company CA root, or a cafile setting that replaced the public roots.
Where you see it
In npm install, npm ci, npm view and npx, and in any Node.js HTTPS client. npm prints the Node.js error code and the OpenSSL reason:
$ npm install
npm error code UNABLE_TO_GET_ISSUER_CERT_LOCALLY
npm error errno UNABLE_TO_GET_ISSUER_CERT_LOCALLY
npm error request to https://registry.npmjs.org/express failed, reason: unable to get local issuer certificate
npm error A complete log of this run can be found in: /home/dev/.npm/_logs/2026-10-20T09_15_02_311Z-debug-0.log
Older npm versions print npm ERR! instead of npm error. In Node.js code the same problem appears as code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY'.
What it means
The server’s certificate chain must end at a root certificate that Node.js trusts. npm received the server’s certificate and at least one CA certificate, but could not find the root that issued the top one in its trust store. Node.js uses its own bundled list of public roots by default, not the operating system’s, so a root IT installed on your computer can still be missing for npm.
Likely causes
A TLS-inspection proxy re-signs your traffic
The most common cause on company networks. The proxy decrypts HTTPS and re-signs it with its own CA. Check who issued the registry’s certificate:
openssl s_client -connect registry.npmjs.org:443 -servername registry.npmjs.org </dev/null 2>/dev/null | openssl x509 -noout -issuer
A public registry certificate comes from a public CA. If the issuer names your company or a security product, ask IT for the proxy’s root certificate (PEM format) and add it:
export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/corp-root.pem
npm install
setx NODE_EXTRA_CA_CERTS "C:\certs\corp-root.pem"
NODE_EXTRA_CA_CERTS adds the certificate to Node.js’s built-in roots when the process starts (Node.js CLI documentation); setx takes effect in new terminals. Put the same variable in CI settings and Dockerfiles that run npm ci. Alternatively, if IT installed the root in the operating system, run Node.js with NODE_USE_SYSTEM_CA=1 (Node.js 22.19 and 24.6 or later).
A private registry uses a company CA
Artifactory, Nexus, Verdaccio or GitHub Enterprise servers often have certificates from a company CA. Test the registry with its root:
openssl s_client -connect npm.example.com:443 -servername npm.example.com -CAfile corp-root.pem </dev/null 2>/dev/null | grep 'Verify return code'
Verify return code: 0 (ok) means the root is the only thing missing. Add it with NODE_EXTRA_CA_CERTS as above.
A cafile setting replaced the public roots
npm’s cafile and ca settings replace the default roots instead of adding to them (npm config documentation). A cafile that holds only a company root makes the public registry fail with exactly this error. Check:
npm config get cafile
npm config get ca
If either is set, NODE_EXTRA_CA_CERTS is ignored as well, because Node.js does not add extra certificates to an explicit ca list (Node.js CLI documentation). Remove the setting and use NODE_EXTRA_CA_CERTS instead:
npm config delete cafile
npm config delete ca
If you must keep cafile, make it a full bundle: the system bundle (for example /etc/ssl/certs/ca-certificates.crt on Debian and Ubuntu) with your company root added by update-ca-certificates.
Node.js or the CA bundle is outdated
An old Node.js bundles an old set of public roots. Upgrade to a supported Node.js release.
Related: the server leaves out its intermediate
If the code is UNABLE_TO_VERIFY_LEAF_SIGNATURE instead, the server sends its certificate without the intermediate. See UNABLE_TO_VERIFY_LEAF_SIGNATURE.
Check yours
Paste the certificates from openssl s_client -showcerts -connect registry.npmjs.org:443. The checker shows the chain, names the root it ends at, and points out root names that belong to known HTTPS-inspection products.
Learn why
- Who do we trust? CAs, trust stores and self-signed certificates: why Node.js has its own store and what TLS inspection does.
- Certificate chains and path validation
- Related: SELF_SIGNED_CERT_IN_CHAIN, verify error:num=20.
Early edition. Checked against the standards; an independent expert review is in progress. Found a mistake? Tell us.