TLS client certificate required -- mTLS handshake failure
curl: (35) error:14094410:ssl routines:ssl3_read_bytes:sslv3 alert handshake failure when connecting to mTLS endpoint
Focused incident mode — strips away everything but this runbook.
Symptoms
- curl: (35) error:14094410:ssl routines:ssl3_read_bytes:sslv3 alert handshake failure when connecting to mTLS endpoint
- openssl s_client returns 'SSL handshake has read 7 bytes and written 0 bytes' with no certificate presented
- Application logs show 'client sent no certificate' or 'certificate required'
mTLS is common in service meshes (Istio, Linkerd) and internal APIs. Always ensure the client cert, key, and CA chain are all present and valid.
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
Server mTLS configuration
openssl s_client -connect <HOST>:<PORT> 2>&1 | grep -i 'verify|acceptable client cert'Client certificate offered
openssl s_client -connect <HOST>:<PORT> -cert client.crt -key client.key 2>&1 | grep 'Verify return'
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- curl without --cert fails with handshake error
- openssl s_client without -cert shows no client certificate sent
Confirm before fixing
curl -v --cacert ca.crt https://<HOST>/ 2>&1 | grep -i 'ssl|cert|handshake'Test curl without client certificate to confirm the error
Fix
curl --cert client.crt --key client.key --cacert ca.crt https://<HOST>/Connect with the client certificate and key
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
openssl s_client -connect <HOST>:<PORT> 2>&1 | grep -i 'verify|error'Confirm mTLS is required (no client cert)
openssl x509 -in client.crt -noout -dates -issuerCheck client certificate validity
openssl s_client -connect <HOST>:<PORT> -cert client.crt -key client.key 2>&1 | grep 'Verify return'Test with the client certificate
Prevention
- Automate client certificate rotation with cert-manager or an internal CA.
- Monitor client certificate expiry and alert at least 7 days before expiration.
- Document the expected client certificate identity (CN/SAN) for every mTLS endpoint.
- Use mutual TLS in service meshes with automatic mTLS between sidecar proxies.
Related runbooks
Same stack, same failure family — worth a skim.
curl: (35) error:14094410:ssl routines:ssl3_read_bytes:sslv3 alert handshake failure
curl: (60) SSL certificate problem: certificate has expired
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.