The cert chain is incomplete: the server sent its leaf certificate but not the intermediates needed to build a path to a trusted root. Fix the SERVER's chain — client-side workarounds just mask it.
fullchain.pem vs cert.pem confusion: nginx/HAProxy configured with only the leaf. Browsers paper over it (AIA fetching/caching), strict clients fail. openssl s_client shows exactly which chain is sent.
Containers based on slim images, old CA bundles, or JVM cacerts missing the root. Less common than the server-side chain gap, but real: check whether OTHER sites verify from the same client.
openssl s_client -connect host:443 -servername host -showcerts </dev/null | grep -c 'BEGIN CERT' # should be 2+ (leaf + intermediate)
# ssl_certificate /etc/letsencrypt/live/host/fullchain.pem; (not cert.pem)
openssl verify -CAfile ca.crt -untrusted intermediate.crt leaf.crt
# Debian: apt-get install --reinstall ca-certificates ; containers: use a current base image (alpine: apk add ca-certificates)
SSLLabs test grades this as an incomplete chain and names the missing intermediate — the fastest external confirmation. This error, unlike self-signed, means the CA hierarchy is fine — the delivery of it is broken. That's why the correct fix lives on the server.
Browsers fetch or cache missing intermediates on their own. curl, Python, Java and most server-side clients don't — they build chains only from what the server sends plus their local store.
Only by weakening the client (bundling intermediates or skipping verification). The durable fix is the server sending fullchain — every client benefits and no security exception is needed.
Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.
Browse the template store →One-time. Yours to modify. Instant download from the NinjaOps template store.