Node.js "DEPTH_ZERO_SELF_SIGNED_CERT" in CI
DEPTH_ZERO_SELF_SIGNED_CERT means the leaf certificate at depth 0 signs itself: there is no chain at all, just a single self-signed certificate. This differs from SELF_SIGNED_CERT_IN_CHAIN, where a self-signed root sits above a real leaf. It shows up when Node talks to an internal or staging endpoint that uses a bare self-signed certificate. Trust that exact certificate to fix it.
What this error means
A Node HTTPS request to an internal or local endpoint fails with "Error: self-signed certificate" and code: 'DEPTH_ZERO_SELF_SIGNED_CERT'.
Error: self-signed certificate
at TLSSocket.onConnectSecure (node:_tls_wrap:1544:34)
code: 'DEPTH_ZERO_SELF_SIGNED_CERT'Common causes
The endpoint uses a bare self-signed certificate
An internal, staging, or local service presents a single self-signed leaf with no issuing CA, so Node has nothing to trust.
A test service generated an ad hoc certificate
A service spun up in CI created its own self-signed certificate that Node has never seen.
How to fix it
Trust the specific self-signed certificate
- Export the endpoint's self-signed certificate as PEM.
- Load it into Node via NODE_EXTRA_CA_CERTS.
- Re-run the request against the endpoint.
echo | openssl s_client -connect localhost:8443 2>/dev/null \
| openssl x509 > selfsigned.pem
export NODE_EXTRA_CA_CERTS=$PWD/selfsigned.pemPass the CA to the request explicitly
For a single client, supply the certificate as ca in the request options instead of a global env var.
const https = require('node:https');
const fs = require('node:fs');
https.get('https://localhost:8443', {
ca: fs.readFileSync('selfsigned.pem'),
}, res => res.resume());How to prevent it
- Issue internal certificates from a small internal CA rather than bare self-signed leaves.
- Provide the test certificate to Node via NODE_EXTRA_CA_CERTS in CI.
- Avoid NODE_TLS_REJECT_UNAUTHORIZED=0 outside a temporary debug run.