highAdvancedSymptom-first#mtls#client-cert#tls#authentication#mutual-tls

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

Likely source:securityconfiguration

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'
READ

Test curl without client certificate to confirm the error

Fix

curl --cert client.crt --key client.key --cacert ca.crt https://<HOST>/
READ

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.

1
openssl s_client -connect <HOST>:<PORT> 2>&1 | grep -i 'verify|error'
READ

Confirm mTLS is required (no client cert)

2
openssl x509 -in client.crt -noout -dates -issuer
READ

Check client certificate validity

3
openssl s_client -connect <HOST>:<PORT> -cert client.crt -key client.key 2>&1 | grep 'Verify return'
READ

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.

Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.