dotvitals

Certificate chain is missing an intermediate

HighConfirmedQuick wintls.certificate.chain-incomplete

What this check looks for

The server sent its own certificate but not the linking certificates above it. Some visitors see the site fine and others get a security warning, seemingly at random.

Why it matters

This is the most confusing TLS failure there is, because it works in the browser you tested with. Browsers quietly download the missing link or reuse a cached copy; mobile apps, cURL, Java clients and payment webhooks do not, and they fail.

When the check passes, your report says: “The server sends the full chain, intermediates included”.

What it costs your score

When this check fails it removes 25 points from your TLS score, before the status, confidence and repeat multipliers are applied. TLS carries a weight of 15 in the overall score.

It shares the tls.certificate family ceiling of 60 points: however many findings that family produces, together they cannot remove more than that from TLS. One underlying problem showing up in several places is still one problem.

Severity
high
Default confidence
confirmed
Status when triggered
fail
Deduction
25 points
Family cap
tls.certificate · 60
Category
TLS
Module
Tls certificate
Fix owned by
user
In the ruleset since
2026.09

How the whole score is calculated

How to fix it

Serve the full chain: leaf first, then every intermediate, and not the root.

Clients that do not fetch the missing certificate themselves cannot verify the site at all.

  1. Point the server at the CA's fullchain file rather than at the leaf-only cert file.

  2. Order matters: leaf, then each issuer in turn.

  3. Do not append the root — it adds bytes to every handshake and is ignored.

  4. Reload the server and re-test from a client with an empty cache.

How to confirm it worked

  • openssl s_client -connect ‹host›:443 -servername ‹host› -showcerts </dev/null 2>/dev/null | grep -c 'BEGIN CERTIFICATE' — expect 2 or more

A named slot like ‹domain› — and the braces left in the configuration below — is filled in with your own values when this rule appears on a report.

Remediation by platform

nginx
# Use fullchain.pem, not cert.pem — cert.pem is the leaf on its own.
ssl_certificate     /etc/letsencrypt/live/‹host›/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/‹host›/privkey.pem;
Apache
SSLCertificateFile    /etc/letsencrypt/live/‹host›/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/‹host›/privkey.pem
Caddy
‹host› {
	tls /etc/ssl/‹host›/fullchain.pem /etc/ssl/‹host›/privkey.pem
}
HAProxy
# HAProxy expects one PEM containing the private key, the leaf and the intermediates.
cat privkey.pem fullchain.pem > /etc/haproxy/certs/‹host›.pem
  • SSLCertificateChainFile has been ignored since Apache 2.4.8; put the chain in SSLCertificateFile.

  • Caddy assembles the chain itself for certificates it manages; this applies only to a certificate you supply.

Technical detail

The chain presented for ‹host› is ‹chain length› certificate(s) long and does not include an issuer for ‹missing issuer›. RFC 5280 §6.1 requires the client to build a path to a trust anchor; TLS servers are expected to supply every certificate except the root. Browsers paper over the gap with AIA fetching and cached intermediates, which is why the symptom is intermittent rather than absolute.

Standards and references

Test this on your domain

Run the check that produces this finding, on its own, against any domain.

Open the tls certificate checkerBuild the fix

Other tls certificate checks