This error occurs when Node.js cannot verify the SSL/TLS certificate of a server you are trying to connect to. It typically happens with self-signed certificates, expired certificates, or missing intermediate certificates. The fix depends on whether you are in a development environment or production.
This error indicates that Node.js's built-in TLS/SSL verification has rejected a certificate during an HTTPS connection attempt. Node.js maintains a list of trusted Certificate Authorities (CAs) and validates all certificates against this list by default. When you encounter this error, it means the certificate presented by the server is either self-signed (not issued by a recognized CA), expired, or part of a certificate chain that cannot be traced back to a trusted root CA. This is Node.js protecting you from potentially insecure connections. While certificate errors often indicate legitimate security concerns, they can also occur in controlled environments where self-signed certificates are intentionally used, such as internal corporate networks, development/staging servers, private package registries, or internal APIs.
Before bypassing certificate validation, confirm this is expected and not a security issue:
# Check certificate details
openssl s_client -connect example.com:443 -showcerts
# Look for "Verify return code" in the output
# If it shows "self signed certificate" or "unable to verify", note the issuerCheck if you recognize the certificate authority. Only proceed with fixes if you trust the server.
The most secure and production-ready solution is to add your custom CA certificate to Node.js's trusted certificate list:
# Save your CA certificate to a file (e.g., ca-cert.pem)
# Then set the environment variable before running Node.js
export NODE_EXTRA_CA_CERTS=/path/to/ca-cert.pem
node your-app.jsOr add it to your start script in package.json:
{
"scripts": {
"start": "NODE_EXTRA_CA_CERTS=./certs/ca-cert.pem node app.js",
"dev": "NODE_EXTRA_CA_CERTS=./certs/ca-cert.pem node --watch app.js"
}
}This method is safe because it explicitly trusts only your specific certificate without disabling validation entirely.
For programmatic control within your application, provide the CA certificate in your HTTPS request configuration:
const https = require('https');
const fs = require('fs');
const options = {
hostname: 'your-server.com',
port: 443,
path: '/api',
method: 'GET',
ca: fs.readFileSync('./path/to/ca-cert.pem')
};
https.request(options, (res) => {
console.log('Connected successfully');
}).end();For popular libraries like Axios or node-fetch:
const axios = require('axios');
const https = require('https');
const fs = require('fs');
const agent = new https.Agent({
ca: fs.readFileSync('./path/to/ca-cert.pem')
});
axios.get('https://your-server.com/api', { httpsAgent: agent });This approach gives you fine-grained control per request.
If intermediate certificates are missing, obtain them from your Certificate Authority and create a complete chain file:
# Concatenate certificates in order: leaf cert, intermediate(s), root CA
cat server.crt intermediate.crt root-ca.crt > full-chain.pem
# Verify the chain is valid
openssl verify -CAfile full-chain.pem server.crtThen use this complete chain file with NODE_EXTRA_CA_CERTS or the ca option.
If the error occurs during npm install with a private registry:
# Set npm to use your custom CA certificate
npm config set cafile /path/to/ca-cert.pem
# Or configure for a specific registry
npm config set registry https://your-private-registry.com
npm config set cafile /path/to/ca-cert.pem
# For a single installation
npm install --cafile=/path/to/ca-cert.pemFor Yarn:
yarn config set cafile /path/to/ca-cert.pemOlder Node.js versions may have outdated CA certificate bundles that do not recognize newer CAs:
# Check current version
node --version
# Update using nvm (recommended for developers)
nvm install --lts
nvm use --lts
# Or download from nodejs.org and installAfter updating, test if the error persists before implementing other fixes. Newer Node.js versions have more up-to-date root certificates.
Why you should NEVER disable certificate validation in production:
While you may see recommendations to use NODE_TLS_REJECT_UNAUTHORIZED=0 or rejectUnauthorized: false, these completely disable certificate validation and expose your application to man-in-the-middle attacks. Never use these approaches in production code:
// ❌ NEVER DO THIS IN PRODUCTION
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
// ❌ ALSO NEVER DO THIS
const agent = new https.Agent({ rejectUnauthorized: false });These shortcuts should only be used in controlled local testing environments and must be accompanied by comments explaining why.
Corporate proxy and firewall environments:
If you are behind a corporate proxy that intercepts HTTPS traffic, your company likely provides a custom CA certificate bundle. To resolve this:
1. Contact your IT/Security department to obtain the corporate root CA certificate(s) and any intermediate certificates
2. Request detailed instructions for installing them for Node.js specifically
3. Store certificates in a secure location accessible to your application
4. Use NODE_EXTRA_CA_CERTS or the programmatic ca option with the certificate bundle
Docker and containerized environments:
When running Node.js in containers, you need to add CA certificates to the container image:
# Copy CA certificate into container
COPY ca-cert.pem /usr/local/share/ca-certificates/company-ca.crt
# Update CA certificates (for Debian/Ubuntu-based images)
RUN update-ca-certificates
# Set environment variable for Node.js to use the certificate
ENV NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/company-ca.crtPrivate registries and internal services:
For npm registries, Docker registries, or internal APIs with self-signed certificates:
- Store the CA certificate in version control (or in a secrets management system for production)
- Document the certificate location and chain order for your team
- Automate certificate updates when they rotate
- Monitor certificate expiry dates to prevent outages
Debugging certificate chains:
To troubleshoot which certificates are being presented:
# View the complete certificate chain
openssl s_client -connect example.com:443 -showcerts
# Check certificate validity dates
openssl s_client -connect example.com:443 | openssl x509 -text -noout | grep -A2 "Validity"
# Verify a certificate chain
openssl verify -CAfile full-chain.pem server.crtError: EMFILE: too many open files, watch
EMFILE: fs.watch() limit exceeded
Error: Middleware next() called multiple times (next() invoked twice)
Express middleware next() called multiple times
Error: Worker failed to initialize (worker startup error)
Worker failed to initialize in Node.js
Error: EMFILE: too many open files, open 'file.txt'
EMFILE: too many open files
Error: cluster.fork() failed (cannot create child process)
cluster.fork() failed - Cannot create child process