TLS 'certificate has expired' after credential renewal: does Node.js reload the secureContext automatically?
0 reputation · 19 Aug 2026, 11:28 UTC
0 reputation · 19 Aug 2026, 11:28 UTC
We run a Node.js HTTPS server (current LTS line, using the built-in tls/https modules) with mutual TLS enabled and rejectUnauthorized: true. Client and server certificates are issued by an internal CA with short validity windows, so renewal happens on a schedule without restarting the process.
After a renewal, the new certificate and key files are written to disk, but existing and new connections still appear to be negotiated against the original SecureContext created at startup. Eventually peers begin failing TLS verification with certificate-validity errors such as certificate has expired, even though the renewed files on disk are valid. The only reliable workaround we have found is recreating the server or rebuilding the context with tls.createSecureContext().
The documentation describes server.setSecureContext() and the SNICallback option, but it is not clear to us what the intended lifecycle is for short-lived credentials in a long-running process, or which validation failures are surfaced to user-land versus handled internally.
Specifically:
SecureContext ever re-read from disk automatically, or must it always be replaced explicitly via setSecureContext()?34775 reputation · 19 Aug 2026, 13:48 UTC
tls.createSecureContext() (or the HTTPS server constructor) runs. To use new files you must explicitly call server.setSecureContext() or rebuild the server.rejectUnauthorized: true the TLS layer itself rejects an expired client certificate during the handshake. The application does not need to perform this check; it will be surfaced as a clientError event on the server and as an error on the client socket.When a server starts, Node.js creates a SecureContext that holds the PEM material in memory. Subsequent reads of the certificate files do not affect that in‑memory object. That is why you saw "certificate has expired" errors after the renewal files appeared on disk – the server was still presenting the old cert.
fs.watch or a cron‑job). When a new cert/key pair is written, read the new PEMs into a buffer.
const ctx = tls.createSecureContext({ cert, key, ca });
httpsServer.setSecureContext(ctx);
The TLS handshake validates the client’s certificate chain before the connection is established. If the client cert is expired, the handshake fails and the server emits a clientError event with an error code such as ERR_TLS_CERT_ALTNAME_INVALID or ERR_TLS_CERT_HAS_EXPIRED. Your application can listen for this event to log or take action, but the rejection itself is guaranteed by the TLS layer.
certificate property or the handshake logs.setSecureContext and the clientError event is consistent across 18+, 20+, and 22+, but checking the exact docs for your version is safest.In short, Node.js does not reload a SecureContext automatically. Explicitly replace it with setSecureContext() for short‑lived credentials, and trust the TLS layer to reject expired client certificates.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.