[Fixed] NPM err code unable_to_get_issuer_cert_locally

Guide to fix npm err code unable_to_get_issuer_cert_locally

Feb 25, 2023 | Read time 8 minutes

🔔 Table of contents

Introduction

When working with NPM/ Node projects, I sometimes come across SSL or certificate errors, like the below error, after running a npm install:

npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY

npm ERR! node v6.10.2
npm ERR! npm  v3.10.10
npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY

npm ERR! unable to get local issuer certificate
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

Another similar example is:

{ Error: unable to get local issuer certificate
    at TLSSocket.<anonymous> (_tls_wrap.js:1116:38)
    at emitNone (events.js:106:13)
    at TLSSocket.emit (events.js:208:7)
    at TLSSocket._finishInit (_tls_wrap.js:643:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:473:38) code: 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY' }

In the above example, I was firing up a react app on my local machine to get started on development.

What does this mean?

This error just means that NPM could not verify the certificate of the registry that you are trying to download the package from.

Usually the cause is that the SSL certificate is not trusted or that your local machine does not have the certificate.

Another reason why this is happening is that you are behind a corporate proxy and its configured for “deep inspection”. What this means is that as NPM tries to connect to the package registry, the proxy will then “swap” the SSL cert with its own to allow it to inspect your traffic.

So there could be automated systems to make your browser trust the root CA cert that issues these certificates, NPM is not configured to trust that Certificate Authority.

We can fix this issue in a few ways:

  1. Disable strict SSL checking strict-ssl=false
  2. Use the HTTP version of the NPM registry
  3. Set NODE_EXTRA_CA_CERTS environment variable
  4. Changing the cafile setting: npm config set cafile /path/to/your/cert.pem
  5. Stop rejecting unknown CAs: set NODE_TLS_REJECT_UNAUTHORIZED=0

1. Disable strict SSL checking strict-ssl=false

If you are unable to obtain the registry’s SSL certificate or are still experiencing issues after adding it to your trusted list, you can temporarily disable strict SSL checking by running the following command:

npm config set strict-ssl false

Note that disabling strict SSL checking can leave your system vulnerable to man-in-the-middle attacks, so it should only be used as a temporary workaround. Once you have resolved the SSL certificate issue, be sure to re-enable strict SSL checking by running:

npm config set strict-ssl true

2. Use the HTTP version of the NPM registry

We can change the registry to use the HTTP version (http://registry.npmjs.org).

The NPM registry is the location where NPM looks for packages when you use the npm install command.

When we first install NPM the public registry is set to HTTPS (https://registry.npmjs.org), however we can change this with the npm config command.

To set the NPM registry for HTTP, follow these steps:

  1. Open a terminal or command prompt window.
  2. Enter the following command to set the registry to the public NPM registry:

npm config set registry http://registry.npmjs.org/

3. Set NODE_EXTRA_CA_CERTS environment variable

The NODE_EXTRA_CA_CERTS environment variable allows you to add additional root certificates to the list of trusted certificates that Node.js and NPM use when making SSL/TLS connections.

This can be useful if you need to connect to a server that uses a certificate signed by a root certificate that is not included in the default list of trusted certificates on your system.

We can set it as follows (Linux or OSX systems):

export NODE_EXTRA_CA_CERTS=path/to/my-certs.pem

If you are on Windows you can do:

set NODE_EXTRA_CA_CERTS=C:\\path\\to\\certificate.pem

When Node.js or an application built on top of it makes an SSL/TLS connection to a server, it checks the server’s certificate against a list of trusted root certificates. If the server’s certificate is signed by a trusted root certificate, the connection is allowed. If the certificate is not signed by a trusted root certificate, the connection is rejected.

Note:

The NODE_EXTRA_CA_CERTS environment variable is only read when the Node.js process is first launched. Changing the value at runtime using process.env.NODE_EXTRA_CA_CERTS has no effect on the current process.

4. Changing the cafile setting: npm config set cafile /path/to/your/cert.pem

We can change the CA file with the set cafile command like so:

npm config set cafile /path/to/root/certificate.pem

Note:

these CA settings will override the default “real world” certificate authority lookups that npm uses. If you try and use any public npm registries via https that aren’t signed by your CA certificate, you will get errors.

You can also configure ca string(s) directly.

npm config set ca "cert string"

ca can be an array of cert strings too. In your .npmrc:

ca[]="cert 1 base64 string"
ca[]="cert 2 base64 string"

The npm config commands above will persist the relevant config items to your ~/.npmrc file:

cafile=/path/to/cert.pem

5. Stop rejecting unknown CAs: set NODE_TLS_REJECT_UNAUTHORIZED=0

We can use the environment variable of NODE_TLS_REJECT_UNAUTHORIZED. This variable will tell Node to reject certificates that are not valid or just ignore them.

Certificate checks that could end up being invalid includes: expired, unsigned or trusted by a root CA, does not match hostname, etc

The default value of NODE_TLS_REJECT_UNAUTHORIZED is 1 - reject any certificate thats got verification errors.

NODE_TLS_REJECT_UNAUTHORIZED=0 means that we ignore any certificate issues. This can be useful when we know what we are doing. Keeping this value to 0 exposes you to man in the middle attacks!

To set NODE_TLS_REJECT_UNAUTHORIZED, you can use the following command:

export NODE_TLS_REJECT_UNAUTHORIZED=0

This sets NODE_TLS_REJECT_UNAUTHORIZED to 0, which disables SSL/TLS certificate verification.

unable_to_get_issuer_cert_locally and Proxies

If you are behind a company firewall, you can get this unable_to_get_issuer_cert_locally because the proxy might be swapping the SSL cert with its own certificate to be able to inspect the traffic.

This is case, we just need to contact the company network admin to get the .pem file.

Another option is to download it using Firefox or Chrome by connecting to any website which the certificate is swapped (in this case the NPM registry - https://registry.npmjs.org)

Then you may use NODE_EXTRA_CA_CERTS to provide the certificate file to Node.js.

Summary

In this post, we went over a few ways to fix the error of NPM err code unable_to_get_issuer_cert_locally. This error is caused by NPM not being able to verify the certificate of the registry eg (https://registry.npmjs.org).

The reason for this could be that the SSL certificate is not trusted or your local machine does not have it. We can resolve this with using HTTP registry instead, setting strict-ssl to false, manually add the .pem file to NODE_EXTRA_CA_CERTS and use NODE_TLS_REJECT_UNAUTHORIZED to tell node to ignore all cert issues.

Additionally if you are running npm install behind a corporate firewall/ proxy then it could be that the SSL is swapped to inspect the traffic. In this case you will need to get the .pem file from your network admins and then use NODE_EXTRA_CA_CERTS setting!

👋 About the Author

G'day! I am Huy a software engineer based in Australia. I have been creating design-centered software for the last 10 years both professionally and as a passion.

My aim to share what I have learnt with you! (and to help me remember 😅)

Follow along on Twitter , GitHub and YouTube