Apprendre
curl SSL Errors: Reading Certificate Validation Failures
curl is stricter than a browser and says exactly what failed. That makes it the fastest way to diagnose a certificate problem — as long as you resist reaching for -k.
Lancez un audit DomainLens frais et utilisez le rapport comme liste de priorités.
What each error actually means
These messages are precise. "Unable to get local issuer certificate" means the chain could not be completed — almost always a missing intermediate on the server rather than a problem on the client.
| Message | Cause | Fix |
|---|---|---|
| unable to get local issuer certificate | Chain incomplete, or CA bundle missing | Serve the full chain |
| certificate has expired | Exactly that | Renew and reload the server |
| subject name does not match | Hostname absent from the certificate | Reissue with the right SANs |
| self signed certificate | A self-signed certificate is being served | Install a publicly trusted one |
| self signed certificate in chain | A private CA in the chain | Trust that CA, or use a public one |
| SSL routines::wrong version number | Not TLS on that port | Check port and protocol |
Diagnosing before you work around it
If the server sends one certificate, the chain is incomplete and the fix is on the server. If it sends three and curl still fails, the client's CA bundle is out of date — which is a genuinely different problem.
# Verbose handshake — shows where it stopped
curl -v https://example.com 2>&1 | head -n 25
# How many certificates does the server send?
openssl s_client -connect example.com:443 -showcerts 2>/dev/null \
| grep -c 'BEGIN CERTIFICATE'
# 1 = incomplete chain, the usual culprit
# Which hostnames does the certificate cover?
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -text | grep -A1 'Subject Alternative Name'
# Does it work with an explicit CA bundle?
curl --cacert /etc/ssl/certs/ca-certificates.crt https://example.com
Why -k is not a fix
The -k flag tells curl to skip verification entirely. The request succeeds, which feels like progress, and nothing about the certificate has been repaired. Every browser and every other client still fails.
It is worse than doing nothing in one specific way: it removes the signal. A script running with -k in production has silently opted out of the guarantee TLS exists to provide, and will keep working after the certificate is replaced by an attacker's.
When the client is genuinely at fault
The clock case is worth checking early because it is invisible otherwise: a container with a drifted clock reports certificate errors for perfectly healthy sites. Update the CA bundle first, then check the date, then look at the server. And confirm the server side independently with the SSL checker .
- An old CA bundle — common in long-lived containers and images pinned years ago.
- A corporate TLS-inspecting proxy presenting its own certificate, which the client does not trust.
- A system clock badly wrong, making a valid certificate appear not yet valid or expired.
- A private CA that was never added to the client's trust store.
How DomainLens contributes
curl tells you whether your machine can validate the certificate; an external check tells you whether anyone can. When the two disagree the fault is local, which narrows the search immediately. See installing an SSL certificate for chain configuration, and SSL certificate expired for the most common cause of all.
- What does "unable to get local issuer certificate" mean?
- curl could not build a path from the server certificate to a trusted root. Usually the server is not sending its intermediate certificates; occasionally the client's CA bundle is outdated.
- Is it safe to use curl -k?
- Only for diagnosis. It disables verification entirely, so the connection is no longer protected against interception. Never leave it in production code.
- Why does the browser work but curl fails?
- Browsers are more forgiving: they cache intermediates from other sites and can fetch missing ones. curl validates strictly with what the server sent, so it catches incomplete chains browsers hide.
- How do I trust a private CA for curl?
- Pass it with --cacert for a single request, or add it to the system trust store for every request. Do not disable verification as a substitute.