Skip to content
Latchkey

Node.js "self signed certificate in certificate chain" - Fix TLS in CI

Node could not validate the TLS chain because it ends in a self-signed certificate it does not trust - almost always a corporate proxy re-signing HTTPS. The fix is to trust the proxy’s CA, not to switch verification off.

What this error means

npm install, a fetch, or any HTTPS call fails with self signed certificate in certificate chain (code SELF_SIGNED_CERT_IN_CHAIN). It is environment-specific - it passes on an unproxied machine and fails behind the corporate proxy.

npm / Node output
npm error code SELF_SIGNED_CERT_IN_CHAIN
npm error errno SELF_SIGNED_CERT_IN_CHAIN
npm error request to https://registry.npmjs.org/... failed,
reason: self signed certificate in certificate chain

Common causes

A TLS-intercepting proxy

A corporate proxy terminates TLS and re-signs traffic with its own root CA. Node does not trust that CA, so the chain validation fails with a self-signed-certificate error.

Missing CA bundle on a minimal image

A slim runner image without an up-to-date CA store cannot validate otherwise-legitimate chains.

How to fix it

Trust the proxy’s CA (correct fix)

Point Node and npm at the extra CA file instead of disabling verification.

Terminal
# Node: add the corporate root CA
export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/corporate-root.pem
# npm: point at the same CA bundle
npm config set cafile /etc/ssl/certs/corporate-root.pem
npm ci

Never disable verification permanently

Setting NODE_TLS_REJECT_UNAUTHORIZED=0 makes Node accept any certificate - it turns off the protection that catches real interception. Use it only to confirm the diagnosis, never as the fix.

Terminal
# diagnosis ONLY - do not leave this set
NODE_TLS_REJECT_UNAUTHORIZED=0 node -e "require('https').get('https://registry.npmjs.org', r=>console.log(r.statusCode))"

How to prevent it

  • Install the proxy’s root CA into the runner image and use NODE_EXTRA_CA_CERTS.
  • Keep ca-certificates current on runner images.
  • Never leave NODE_TLS_REJECT_UNAUTHORIZED=0 set in CI.

Frequently asked questions

What causes ""self signed certificate in chain""?
A corporate proxy terminates TLS and re-signs traffic with its own root CA. Node does not trust that CA, so the chain validation fails with a self-signed-certificate error.
How do I fix "self signed certificate in chain"?
Point Node and npm at the extra CA file instead of disabling verification.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card