[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:
- Disable strict SSL checking
strict-ssl=false
- Use the HTTP version of the NPM registry
- Set
NODE_EXTRA_CA_CERTS
environment variable - Changing the cafile setting:
npm config set cafile /path/to/your/cert.pem
- 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:
- Open a terminal or command prompt window.
- 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!