golang/go · error
tls: server resumed a session with a different cipher suite
Error message
tls: server resumed a session with a different cipher suite
What it means
A resumed session must reuse the original cipher suite. If hs.session.cipherSuite != hs.suite.id the server resumed with a different suite than the original handshake, which TLS forbids and aborts with alertHandshakeFailure.
Source
Thrown at src/crypto/tls/handshake_client.go:943
c.sendAlert(alertUnsupportedExtension)
return false, err
}
c.clientProtocol = hs.serverHello.alpnProtocol
c.scts = hs.serverHello.scts
if !hs.serverResumedSession() {
return false, nil
}
if hs.session.version != c.vers {
c.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: server resumed a session with a different version")
}
if hs.session.cipherSuite != hs.suite.id {
c.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: server resumed a session with a different cipher suite")
}
// RFC 7627, Section 5.3
if hs.session.extMasterSecret != hs.serverHello.extendedMasterSecret {
c.sendAlert(alertHandshakeFailure)
return false, errors.New("tls: server resumed a session with a different EMS extension")
}
// Restore master secret and certificates from previous state
hs.masterSecret = hs.session.secret
c.extMasterSecret = hs.session.extMasterSecret
c.peerCertificates = hs.session.peerCertificates
c.verifiedChains = hs.session.verifiedChains
c.ocspResponse = hs.session.ocspResponse
// Let the ServerHello SCTs override the session SCTs from the original
// connection, if any are provided.
if len(c.scts) == 0 && len(hs.session.scts) != 0 {
c.scts = hs.session.sctsView on GitHub (pinned to b6b368adc5)
Solutions
- Rotate the server's session ticket key to invalidate inconsistent cached state.
- Upgrade the server TLS stack.
- Disable client-side session resumption (SessionTicketsDisabled = true) if the server is unfixable.
Example fix
cfg := &tls.Config{SessionTicketsDisabled: true} Defensive patterns
Strategy: fallback
Type guard
func isResumptionCipherMismatch(err error) bool {
return err != nil && strings.Contains(err.Error(), "server resumed a session with a different cipher suite")
} Try / catch
if _, err := tls.Dial("tcp", addr, cfg); err != nil {
if isResumptionCipherMismatch(err) {
cfg.SessionTicketsDisabled = true
cfg.ClientSessionCache = nil
_, err = tls.Dial("tcp", addr, cfg)
}
} Prevention
- Rotate server ticket keys when cipher policies change.
- Disable resumption against non-conformant servers.
When it happens
Trigger: Server resuming a session but picking a different cipher suite; ticket corruption; server bug in resumption state binding.
Common situations: Misconfigured server resumption cache; rare.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: server resumed a session with a different version
- tls: server resumed a session with a different EMS extension
- tls: server echoed TLS 1.3 compatibility session ID in TLS 1
- tls: server chose an unconfigured cipher suite
- tls: received unexpected CertificateStatus message
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/27c7e454297083ba.
Report an issue: GitHub.