Serve local HTTPS

Serve a complete chain

Configure a server to send its leaf and intermediate certificates in the correct order.

10 minute lesson

~~~

So far our chain has been short: leaf, root, done. Real deployments almost always have at least one intermediate CA between them. That changes what the server must send. A client may trust the root but lack your intermediate — the server must provide the leaf followed by required intermediates so clients can build the path from the certificate they received up to a root they hold.

The standard fix is a full-chain file: the leaf first, then each intermediate, concatenated in order. PEM files stack cleanly, so this is one command.

Combine a lab leaf and intermediate for server use:

cat app.crt lab-intermediate.crt > app-fullchain.crt

Order matters. The leaf comes first because TLS requires the server’s own certificate at the start; each following certificate should sign the one before it. This is the same layout tools like certbot produce when they hand you a fullchain.pem.

Point the server at the full chain by loading it as the cert value:

cert: fs.readFileSync('app-fullchain.crt'),

Node sends every certificate in the file, in file order. The key option does not change — the private key still corresponds only to the leaf. Intermediates are public certificates; no key material for them belongs anywhere near your server.

Verify what the server now presents with s_client -showcerts:

openssl s_client -connect app.lab.test:8443 -showcerts </dev/null 2>/dev/null | grep -c 'BEGIN CERTIFICATE'
# 2

Two PEM blocks means both the leaf and the intermediate went out. Run without the grep to read the s: and i: lines and confirm the order: certificate 0 should be app.lab.test, certificate 1 the intermediate.

The classic mistake here is subtle because it half-works. A server sending only the leaf passes tests in browsers that cached the intermediate from an earlier visit somewhere else, then fails in curl, CI, or mobile apps with unable to get local issuer certificate. If a TLS error appears only on some clients, suspect the chain before anything else.

Two things never belong in a full-chain file. Do not include a private key — the file gets sent to every client. And do not include the root: clients must already hold it, they ignore a root you send, and you waste bytes on every handshake.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →