Fix npm Error: unable to get local issuer certificate

By 

•

Published on

•

9 min read

Certificate cards connected by a repaired link, illustrating npm certificate verification

You run npm install and the command fails with npm error code UNABLE_TO_GET_ISSUER_CERT_LOCALLY and the message unable to get local issuer certificate. The registry may open normally in a browser, but npm cannot verify its HTTPS connection.

This guide explains what the error means and how to fix it by trusting the correct certificate authority while keeping TLS verification enabled.

What the Error Means

A typical failure looks like this:

output
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

When npm connects to a registry over HTTPS, Node.js checks the server’s certificate against a list of trusted certificate authorities. To trust the server, Node must follow the chain from the server certificate up to a root CA it already has. UNABLE_TO_GET_ISSUER_CERT_LOCALLY means it could not find an issuer needed to complete that chain, so the connection fails.

Common causes include:

  • A corporate proxy, firewall, or antivirus that inspects HTTPS and signs certificates with an internal CA.
  • A private registry whose certificate was issued by a CA that Node does not trust.
  • A registry or proxy that does not send a required intermediate certificate.
  • An outdated CA bundle, or an npm setting that points to the wrong certificates.

Node.js normally uses its own bundled root certificates. Your browser may trust an internal CA through a different certificate store, which explains why the browser works while npm fails. The Node.js enterprise network guide describes the available trust settings.

Check the npm Configuration

Before we change certificate settings, check the Node.js version and npm configuration from the directory where the install fails:

Terminal
node --version
npm config get registry
npm config get cafile
npm config get ca
npm config get strict-ssl

The public registry is https://registry.npmjs.org/. The ca and cafile settings normally return null, and strict-ssl should return true. A configured cafile is not necessarily wrong, but the file must contain the CA certificates needed for your registry. If you previously disabled verification, restore it before testing the connection.

npm reads settings from several places. A project’s .npmrc overrides your user configuration, usually ~/.npmrc. Environment variables and command-line options can override both, so check those sources if a setting differs from what you expect.

Scoped packages can use a separate registry. Replace @myorg with your package scope and check its mapping:

Terminal
npm config get @myorg:registry

If this returns a URL, packages under that scope use that registry. Also check the URL in the original error: the failed connection may be to a package download host rather than the default registry.

Find the Missing Certificate

On a managed workstation, ask your IT team for the root CA used by the HTTPS inspection proxy. For a private registry, ask its administrator which CA issued the certificate. Obtain the CA from a trusted source; do not copy a certificate from the failed connection and assume it is safe to trust.

The CA file must be in PEM format, with a -----BEGIN CERTIFICATE----- header. A .crt or .cer extension alone does not tell you how the certificate is encoded.

To inspect the certificates presented by the public registry, run:

Terminal
openssl s_client -connect registry.npmjs.org:443 \
  -servername registry.npmjs.org -showcerts </dev/null

For another registry, replace both occurrences of registry.npmjs.org with the hostname from the failed URL. The -servername option sends the hostname so the server can select the right certificate, and -showcerts prints the certificates it sends. The input redirection closes the session without waiting for keyboard input.

Compare the subject and issuer names in the output. An internal CA name can help identify an inspection proxy, but this is not a verified chain, and servers normally omit the root certificate. OpenSSL also uses its own trust settings, so a successful OpenSSL check does not prove that Node trusts the same CA. See the s_client documentation for details.

If npm connects through an explicit HTTP proxy, use that proxy when inspecting the connection. Replace proxy.example.com:8080 with its hostname and port:

Terminal
openssl s_client -proxy proxy.example.com:8080 \
  -connect registry.npmjs.org:443 -servername registry.npmjs.org \
  -showcerts </dev/null

OpenSSL does not read npm’s proxy configuration. Without -proxy, you may inspect a direct connection that presents different certificates from the connection npm uses.

Method 1: Trust the CA Certificate

Save the verified CA file somewhere your user can read it. Replace /path/to/company-ca.pem in the examples below with its absolute path.

To add the CA to Node’s bundled roots, set NODE_EXTRA_CA_CERTS, then test the registry connection:

Terminal
export NODE_EXTRA_CA_CERTS="/path/to/company-ca.pem"
npm ping

A successful npm ping reports PONG. It checks the configured registry without installing packages. Node reads NODE_EXTRA_CA_CERTS when a process starts, so start a new npm command after setting it. For other running Node tools, restart the process too.

To keep the setting across terminal sessions, add the export line to your shell configuration, such as ~/.bashrc for Bash or ~/.zshrc for Zsh. In CI, set the variable in the job environment before npm starts and make the certificate file available to the runner.

Set a CA Bundle for npm Only

If you want the certificate setting to apply to npm only, use cafile instead:

Terminal
npm config set cafile "/path/to/company-ca.pem" --location=user
npm ping

This writes the setting to your user npm configuration. The file can contain one or more PEM CA certificates. Unlike NODE_EXTRA_CA_CERTS, npm’s cafile supplies an explicit CA list that replaces Node’s default trusted roots for those connections. If you need both internal and public CAs, use a bundle that contains the required authorities.

Note
An explicit npm ca or cafile setting takes precedence over NODE_EXTRA_CA_CERTS. Setting the environment variable will not add certificates to npm’s configured CA list. The same applies to Node tools that supply their own TLS ca option.

To switch back to NODE_EXTRA_CA_CERTS, remove the ca and cafile entries you previously added to your user configuration:

Terminal
npm config delete ca cafile --location=user

This changes the user configuration only. Run npm config get ca and npm config get cafile again from your project directory. If either setting is still present, check the project’s .npmrc, the global configuration, and environment variables such as npm_config_cafile. Remove the conflicting setting from the source that defines it.

Once npm ping succeeds with verification enabled, retry the install:

Terminal
npm install

If the install still fails, compare its error URL with the registry checked by npm ping. Packages can be downloaded from other hosts, which may need a different certificate chain.

Method 2: Use the System CA Store

If the system certificate bundle is missing or outdated, reinstall it and rebuild the store. You can also add an internal CA to the system store when other applications need it.

Ubuntu, Debian, and Derivatives

Reinstall the ca-certificates package and rebuild the store:

Terminal
sudo apt update
sudo apt install --reinstall ca-certificates
sudo update-ca-certificates

To add a verified internal CA, copy it into /usr/local/share/ca-certificates/ with a .crt extension, then update the store:

Terminal
sudo cp /path/to/company-ca.pem /usr/local/share/ca-certificates/company-ca.crt
sudo update-ca-certificates

The certificate must be PEM encoded, with one certificate per file. If your CA bundle contains several certificates, install them as separate .crt files. The update-ca-certificates manual explains these requirements.

Fedora, RHEL, and Derivatives

Reinstall the certificate package and regenerate the trust store:

Terminal
sudo dnf reinstall ca-certificates
sudo update-ca-trust extract

To add a verified internal CA, place it in the system’s trust anchors directory:

Terminal
sudo cp /path/to/company-ca.pem /etc/pki/ca-trust/source/anchors/company-ca.pem
sudo update-ca-trust extract

The second command rebuilds the trust store with the added CA. Red Hat documents this process in its guide to shared system certificates .

Enable System Certificates in Node.js

Updating the system store does not automatically change the certificates used by most Node.js installations. On Node.js 22.19.0 or later in the 22.x series, or Node.js 24.6.0 and later, enable system CAs with:

Terminal
export NODE_USE_SYSTEM_CA=1
npm ping

This adds system CAs alongside Node’s bundled roots. As with NODE_EXTRA_CA_CERTS, an explicit npm ca or cafile setting overrides that trust list. Older Node versions can use the CA file through NODE_EXTRA_CA_CERTS; if the bundled public roots are outdated, update Node.js to a supported release.

Keep TLS Verification Enabled

Setting strict-ssl to false or NODE_TLS_REJECT_UNAUTHORIZED to 0 bypasses certificate verification. It hides the problem by allowing a connection whose certificate cannot be verified.

Warning
Disabling TLS verification allows a third party to impersonate the registry and tamper with package downloads. Trust the correct CA or fix the server’s certificate chain while keeping verification enabled.

If you previously disabled verification, restore it with:

Terminal
npm config set strict-ssl true --location=user
unset NODE_TLS_REJECT_UNAUTHORIZED
npm config get strict-ssl

The last command should return true. If it does not, check for an override in the project’s .npmrc or environment. Also remove any NODE_TLS_REJECT_UNAUTHORIZED=0 assignment from your shell configuration or CI settings so it does not return in the next session.

Troubleshooting

NODE_EXTRA_CA_CERTS does not fix the error
Check for an overriding ca or cafile setting first. Confirm that the file is readable and contains PEM certificates, then start a new npm command. A running Node process does not reload the variable when you change it.

npm ping works, but npm install still fails
Check the URL in the install error. A scoped registry, a tarball URL in package-lock.json, or a Git dependency may connect to another host. An install script may also run a tool with its own certificate settings. Diagnose that connection separately.

The install works locally but fails in CI or a container
The runner or container has its own environment and certificate store. Copy the trusted CA into that environment, set the certificate variable before npm starts, and confirm the path is readable there. A host’s user .npmrc or system CA store is not automatically available inside a container.

A private registry sends an incomplete chain
Ask its administrator to configure the registry or reverse proxy to send the server certificate and required intermediate certificates. Adding a root CA on the client does not replace a missing intermediate in the server’s chain.

Conclusion

In most cases, the fix is trusting the right CA through NODE_EXTRA_CA_CERTS or cafile, not turning off strict-ssl. For more on inspecting certificate chains, see our guide on using OpenSSL . The npm command reference covers package installation and the other commands you will use after the connection is working.

Tags

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page