Website problems
Incomplete certificate chain
A server must send its own certificate plus the intermediate certificates linking it to a trusted root. When the intermediates are missing, validation depends on whether the client already holds them — which desktop browsers frequently do, through caching or their own fetching, and which most other clients do not. The result is a site that works in the browser you tested with and fails for command-line tools, mobile applications, payment callbacks and other servers.
Why some clients cope
Desktop browsers cache intermediates they have seen before, so a common intermediate is frequently already present.
Some clients fetch a missing intermediate from a location named in the certificate, which is an extra round trip that usually succeeds.
Both of those are tolerances rather than correctness, and neither is guaranteed.
A freshly installed browser, a private window on a new machine or a different operating system may have neither the cache nor the fetching behaviour.
Which is why the symptom is reported as intermittent when it is entirely deterministic per client.
Which clients do not cope
Command-line HTTP clients, which validate strictly and do not fetch missing intermediates.
Server-to-server calls, including webhooks and payment provider callbacks — these fail silently and are noticed as missing events.
Mobile applications using the platform's networking stack, which vary and frequently do not fetch.
Older devices whose trust stores are not updated, which is a different failure with the same appearance.
Monitoring and uptime services, which is occasionally how the problem is discovered at all.
How it happens
A certificate installed by copying only the certificate file, without concatenating the intermediates the authority supplied alongside.
A renewal where the new certificate is installed and the chain file is not updated, which matters when the authority rotates its intermediate.
A load balancer configured with the certificate in one field and the chain in another that was left empty.
A manual installation on a second server where the first one's full configuration was not reproduced.
An automated client handles all of this correctly, which is one more argument for automation over manual installation.
The adjacent failures it resembles
An expired certificate, which was trusted and no longer is.
A hostname mismatch, where a valid certificate is presented for the wrong name — usually a server selection problem rather than a certificate one.
A self-signed certificate, which is a deliberate configuration no public client accepts.
An untrusted root, where the authority itself is not in the client's trust store.
Browsers present all of these similarly, so reading what the certificate actually says matters before diagnosing.
How to check it yourself
`openssl s_client -connect example.com:443 -showcerts` prints every certificate the server sent.
Count them: a leaf certificate alone is the defect, and a leaf plus one or two intermediates is normal.
The root does not need to be sent — clients have it — and sending it is harmless but pointless.
Test with a client that does not fetch missing intermediates, which is what makes the failure visible.
Test each hostname and each server behind a load balancer, since the configuration is per installation.
How to fix it
Obtain the full chain file from the certificate authority, which every one of them provides alongside the certificate.
Install the leaf and the intermediates together, in order from leaf outward, in whatever form the server expects.
Reload rather than restart where the server supports it, so connections are not dropped.
Verify from outside afterwards, with a client that validates strictly.
Prefer an automated client that handles the chain on every renewal, since this is a failure that returns at renewal time.
How VeriFixScan detects it
`transport.certificate_details` reports the certificate really presented and the chain sent with it.
`transport.certificate_coverage` reports whether the certificate covers the hostname, which is the adjacent failure with a similar appearance.
`transport.https` establishes whether HTTPS works at all for a tolerant client, which is what makes this problem easy to miss.
`transport.tls_versions` and `transport.cipher_suites` describe the rest of the same handshake.
The report separates a missing intermediate from an untrusted root, because the two have different causes and different fixes.
Why the chain gets longer and then shorter
Certificate authorities rotate their intermediates on their own schedule, which is why a chain file that was correct becomes stale without your certificate changing.
Some authorities publish two valid chains for the same certificate — a shorter modern one and a longer one for older trust stores — and choosing between them is a real decision.
The longer chain is safer for old devices and adds bytes to every handshake; the shorter one is leaner and fails on trust stores that were never updated.
An automated client picks a default and can usually be told which to prefer, which is worth knowing before an audience with old devices reports failures.
Either way the rule is unchanged: send the leaf and every intermediate, and let the client supply the root.
Frequently asked questions
- Why does my site work in Chrome but fail with curl?
- Most often a missing intermediate certificate. Browsers cache intermediates and some fetch them; strict clients do neither and refuse the connection.
- Should I send the root certificate too?
- No need. Clients already have the roots they trust. Sending it is harmless and adds bytes to every handshake for no benefit.
- Why did this appear after a renewal?
- Usually because the certificate was updated and the chain file was not, or because the authority rotated its intermediate and the old chain no longer links to a trusted root.
Sources
Related
VeriFixScan crawls a site and applies its checks to every page it reaches, keeping the evidence behind each finding. Scanning one website is free.
Scan a website