Hi, I need help with reconnection handshake errors.
After an idle period (5–10 minutes), browsers consistently fail the first TLS handshake to an HAProxy frontend configured with ca-file and verify optional. The retry always succeeds immediately.
Environment: HAProxy 2.9.14, OpenSSL 3.0.16, FreeBSD 15.0-CURRENT (pfSense)
Bind line:
bind :443 ssl crt /path/to/cert.pem ca-file /path/to/ca.pem verify optional crt-ignore-err all
tcpdump capture shows:
-
Browser opens new TCP connection after idle (new source port)
-
Sends small ClientHello (267 bytes — PSK resumption attempt)
-
Server responds with ServerHello + CertificateRequest (3264 bytes)
-
Browser immediately sends FIN — closes connection
-
Browser retries with full ClientHello (1828 bytes, includes client certificate)
-
Handshake succeeds
What I tested (all still fail):
-
verify optionalvsverify required— same behavior -
Removing
no-tls-ticketsfrom bind and globally — same behavior -
tune.ssl.cachesize 0+tune.ssl.lifetime 0— same behavior -
TLS 1.2 only (
ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.2) — same behavior -
Direct bind on WAN IP (no TCP proxy/PROXY protocol) — same behavior
What fixes it:
- Removing
ca-filefrom bind completely eliminates the issue
Conclusion: The mere presence of ca-file causes HAProxy/OpenSSL to send CertificateRequest during the handshake. After idle, the browser attempts PSK resumption without a client certificate ready, receives CertificateRequest, and aborts. This appears to be browser behavior (tested with Chrome/Edge), but I’m wondering:
-
Is there a way to suppress
CertificateRequestduring session resumption while keepingca-filefor new connections? -
Should
verify optionalprevent sendingCertificateRequestwhen the client hasn’t offered a certificate in ClientHello? -
Is this a known interaction between OpenSSL 3.0 session resumption and post-handshake authentication?
Workaround: I’m using a TCP frontend that routes whitelisted IPs to a backend without ca-file, and other IPs to the mTLS backend. This works but is complex.