How to fix Error: tlsv1 alert bad certificate (peer rejected certificate) in Node.js
The remote server rejected the SSL/TLS certificate presented by your Node.js application during the handshake. This occurs when the certificate is invalid, self-signed, or the certificate chain is incomplete.
Quick fix
Fixes Error: tlsv1 alert bad certificate (peer rejected certificate)
openssl x509 -in your-certificate.pem -text -noout | grep -A 2 "Validity"- Verify the certificate validity and dates
- Check the certificate subject and SAN
- Verify the complete certificate chain
- Ensure proper certificate format and encoding
openssl x509 -in your-certificate.pem -text -noout | grep -A 2 "Validity"Error: tlsv1 alert bad certificate (peer rejected certificate)
What this error means
This error occurs when Node.js initiates an HTTPS connection to a remote server, and the server rejects the TLS certificate that Node.js presents. This is different from a client-side rejection (where the client rejects the server's certificate); here, the server is telling Node.js "I don't accept your certificate." The "tlsv1 alert bad certificate" message is a TLS protocol-level alert indicating that the peer found the presented certificate unacceptable. This typically happens when: - The certificate is self-signed or not signed by a trusted CA - The certificate chain is incomplete or missing intermediate certificates - The certificate has expired or is not yet valid - The certificate CN/SAN doesn't match the expected domain - The server has stricter certificate validation enabled
Typical symptoms
- HTTPS requests to a specific server fail with TLS alert error
- The application works fine with different servers but fails with one particular endpoint
- Error occurs during the TLS handshake, before any data is sent
- Adding --insecure flag or disabling certificate validation temporarily fixes the issue
- Other clients (curl, browsers) may accept the same certificate without issues
Common causes
- Server is configured to reject certificates it doesn't recognize (mutual TLS/mTLS without proper client certificate)
- Client certificate is self-signed and not in the server's trusted CA store
- Client certificate chain is incomplete (missing intermediate certificates)
- Client certificate CN/SAN (Subject Alternative Name) doesn't match the connection details
- Client certificate has expired or not yet become valid
- Server requires certificate pinning and your certificate doesn't match the pinned hash
- Misconfigured mutual TLS (mTLS) authentication requiring specific client certificates
How to fix "Error: tlsv1 alert bad certificate (peer rejected certificate)"
Check if your client certificate is still valid:
openssl x509 -in your-certificate.pem -text -noout | grep -A 2 "Validity"Look for:
- Not Before date (should be in the past)
- Not After date (should be in the future)
If the certificate has expired, you need to obtain a new one from your Certificate Authority.
Verify the certificate Subject and Subject Alternative Names match what the server expects:
openssl x509 -in your-certificate.pem -text -noout | grep -A 5 "Subject:"
openssl x509 -in your-certificate.pem -text -noout | grep -A 5 "Alternative Name"Ensure the CN (Common Name) or SAN contains the correct domain or identifier that the server is expecting.
Check if you have the complete certificate chain including intermediate certificates:
openssl verify -untrusted chain.pem your-certificate.pemIf the chain is incomplete, request the intermediate certificates from your Certificate Authority and combine them:
cat your-certificate.pem intermediate1.pem intermediate2.pem > full-chain.pemThen use the full chain in your Node.js code:
const https = require('https');
const fs = require('fs');
const tls = require('tls');
const options = {
key: fs.readFileSync('your-key.pem'),
cert: fs.readFileSync('full-chain.pem'), // Use complete chain
ca: fs.readFileSync('server-ca.pem'), // Server's CA if needed
};
const req = https.request('https://server.example.com', options, (res) => {
console.log('Connected');
});Verify your certificate is in the correct format (PEM) and not corrupted:
# Check if it's valid PEM format
openssl x509 -in your-certificate.pem -text -nooutThe file should contain:
- -----BEGIN CERTIFICATE-----
- Base64 encoded data
- -----END CERTIFICATE-----
If you have a DER format certificate, convert it to PEM:
openssl x509 -inform DER -in your-certificate.der -out your-certificate.pemUse OpenSSL to test if the server accepts your certificate:
openssl s_client -connect server.example.com:443 \
-cert your-certificate.pem \
-key your-key.pem \
-CAfile ca.pemThis simulates what Node.js is doing. Look for:
- Verify return code: 0 (ok) - Certificate accepted
- alert bad certificate - Certificate rejected by server
If OpenSSL also fails, the issue is with the certificate itself, not Node.js.
In your Node.js application, ensure you're passing the certificate correctly:
const https = require('https');
const fs = require('fs');
const options = {
hostname: 'server.example.com',
port: 443,
path: '/',
method: 'GET',
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem'),
// Include CA if server uses self-signed or non-standard CA
ca: fs.readFileSync('./ca.pem'),
// Optional: pin certificate for extra security
// checkServerIdentity: (host, cert) => {
// // Custom validation logic
// }
};
const req = https.request(options, (res) => {
console.log('Status:', res.statusCode);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error('Error:', e.message);
});
req.end();Run your Node.js application with TLS debugging enabled to see the exact TLS handshake:
NODE_DEBUG=tls node your-app.jsOr programmatically:
process.env.NODE_DEBUG = 'tls';
// Then require https and make requests
const https = require('https');The output will show the complete TLS handshake and indicate where the certificate validation fails. Look for certificate exchange messages and error alerts.
If you've verified your certificate is valid and properly formatted:
1. Contact the server's administrator and provide your certificate details
2. Ask them to verify their certificate validation rules
3. Request that they add your client certificate (or its CA) to their trust store
4. Confirm they support mTLS if that's what the connection requires
5. Ask if there are specific certificate requirements (key algorithm, signature algorithm, extensions)
Advanced notes
Mutual TLS (mTLS): This error is common in mutual TLS scenarios where both client and server authenticate each other. If this is your use case, ensure:
- Your certificate is signed by a CA that the server trusts
- The certificate includes proper key usage and extended key usage extensions
- The certificate CN/SAN matches what the server expects
Certificate Pinning: If the server uses certificate pinning, ensure your certificate matches the pinned value. You can implement pinning in Node.js by comparing the certificate's public key hash.
Self-Signed Certificates: For development with self-signed certificates, you must explicitly provide the CA:
const options = {
ca: fs.readFileSync('./self-signed-ca.pem')
};Environment Variables: For applications where you cannot modify code, use:
- NODE_EXTRA_CA_CERTS=/path/to/ca.pem - Add custom CAs
- This is cleaner than setting process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' (which disables all validation)
Protocol Version Mismatch: Ensure both client and server support the same TLS version. You can explicitly set the protocol:
const options = {
minVersion: tls.TLS1_2_VERSION,
maxVersion: tls.TLS1_3_VERSION
};Frequently asked questions
- What does "Error: tlsv1 alert bad certificate (peer rejected certificate)" mean?
- js presents. " The "tlsv1 alert bad certificate" message is a TLS protocol-level alert indicating that the peer found the presented certificate unacceptable.
- How do I fix "Error: tlsv1 alert bad certificate (peer rejected certificate)"?
- The remote server rejected the SSL/TLS certificate presented by your Node.js application during the handshake. This occurs when the certificate is invalid, self-signed, or the certificate chain is incomplete.
- What causes "Error: tlsv1 alert bad certificate (peer rejected certificate)"?
- Server is configured to reject certificates it doesn't recognize (mutual TLS/mTLS without proper client certificate) Client certificate is self-signed and not in the server's trusted CA store Client certificate chain is incomplete (missing intermediate certificates)
- Is the "Error: tlsv1 alert bad certificate (peer rejected certificate)" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- ๐Node.js Official Documentation
- ๐Node.js TLS (SSL) Module Documentation(Official Docs)
- ๐
- ๐
- ๐