This repository reproduces postmanlabs/postman-app-support#6354 - the "unable to verify the first certificate" error that occurs when servers don't send intermediate CA certificates.
When a server is configured with an incomplete certificate chain (missing intermediate CA certificates), different tools behave differently:
- ✅ cURL: Often works (may fetch intermediate certs or use lenient validation)
- ✅ Browsers: Often work (cache intermediate certs or fetch them automatically)
- ❌ Node.js (strict SSL): Fails with "unable to verify the first certificate"
- ❌ Postman (SSL verification on): Fails with the same error
- Node.js installed
- OpenSSL installed
chmod +x generate-certs.sh
./generate-certs.shThis creates:
certs/root-ca.crt- Root CA certificatecerts/intermediate-ca.crt- Intermediate CA certificate (the missing link!)certs/server.crt- Server certificate WITHOUT intermediate (causes the issue)certs/server-bundle.crt- Server certificate WITH intermediate (the fix)
node server.jsThe server runs on https://localhost:8443 with an incomplete certificate chain.
chmod +x test-curl.sh
./test-curl.shnode test-client-strict.jsExpected output:
✗ FAILED!
Error: unable to verify the first certificate
This is the same error Postman shows!
node test-client-loose.jsThis simulates Postman with SSL verification disabled.
Start the server with a complete certificate chain:
node server-fixed.jsNow test with strict SSL:
node test-client-strict.js --port 8444This will ✅ succeed because the server sends the complete chain!
SSL/TLS requires a chain of trust from the server certificate up to a trusted root CA:
[Server Certificate]
↓ signed by
[Intermediate CA] ← MISSING in misconfigured servers!
↓ signed by
[Root CA] ← Trusted by client
- cURL: May use a more lenient verification process or cached intermediate certificates
- Browsers: Actively cache intermediate certificates from previous connections
- Node.js/Postman: Strictly require the server to send the complete chain
Servers must send both:
- The server certificate
- All intermediate CA certificates (in order)
In Node.js:
// ❌ Wrong - only server cert
cert: fs.readFileSync('server.crt')
// ✅ Correct - server cert + intermediate(s)
cert: fs.readFileSync('server-bundle.crt')- Import
postman-collection.json(if you create one) - Try request to
https://localhost:8443with SSL verification enabled → Should fail - Disable SSL verification → Should work
- Try request to
https://localhost:8444with SSL verification enabled → Should work (fixed server)
This issue commonly occurs when:
- Self-signed certificates are used without bundling intermediates
- SSL certificates from providers like Namecheap, Let's Encrypt are installed incorrectly
- Only the server certificate is installed, not the full chain
- DevOps teams test with
curl -kand don't notice the issue
generate-certs.sh- Generates test certificatesserver.js- Server with incomplete chain (reproduces issue)server-fixed.js- Server with complete chain (fixed)test-client-strict.js- Node.js client with strict SSL (like Postman)test-client-loose.js- Node.js client with SSL verification disabledtest-curl.sh- Test with cURL
When the chain is incomplete, you'll see:
unable to verify the first certificateUNABLE_TO_VERIFY_LEAF_SIGNATUREUNABLE_TO_GET_ISSUER_CERT_LOCALLY
ssl_certificate /path/to/server-bundle.crt; # Must include intermediates!
ssl_certificate_key /path/to/server.key;SSLCertificateFile /path/to/server.crt
SSLCertificateKeyFile /path/to/server.key
SSLCertificateChainFile /path/to/intermediate.crt # Important!const options = {
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server-bundle.crt') // Includes intermediates
};cat server.crt intermediate.crt > server-bundle.crt# Check what certificates a server sends
openssl s_client -connect localhost:8443 -showcerts
# Verify the certificate chain
openssl verify -CAfile root-ca.crt -untrusted intermediate-ca.crt server.crt