{"record":{"id":"27c7e454297083ba","repo":"golang/go","slug":"tls-server-resumed-a-session-with-a-different-cip","errorCode":null,"errorMessage":"tls: server resumed a session with a different cipher suite","messagePattern":"tls: server resumed a session with a different cipher suite","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client.go","lineNumber":943,"sourceCode":"\t\tc.sendAlert(alertUnsupportedExtension)\n\t\treturn false, err\n\t}\n\tc.clientProtocol = hs.serverHello.alpnProtocol\n\n\tc.scts = hs.serverHello.scts\n\n\tif !hs.serverResumedSession() {\n\t\treturn false, nil\n\t}\n\n\tif hs.session.version != c.vers {\n\t\tc.sendAlert(alertHandshakeFailure)\n\t\treturn false, errors.New(\"tls: server resumed a session with a different version\")\n\t}\n\n\tif hs.session.cipherSuite != hs.suite.id {\n\t\tc.sendAlert(alertHandshakeFailure)\n\t\treturn false, errors.New(\"tls: server resumed a session with a different cipher suite\")\n\t}\n\n\t// RFC 7627, Section 5.3\n\tif hs.session.extMasterSecret != hs.serverHello.extendedMasterSecret {\n\t\tc.sendAlert(alertHandshakeFailure)\n\t\treturn false, errors.New(\"tls: server resumed a session with a different EMS extension\")\n\t}\n\n\t// Restore master secret and certificates from previous state\n\ths.masterSecret = hs.session.secret\n\tc.extMasterSecret = hs.session.extMasterSecret\n\tc.peerCertificates = hs.session.peerCertificates\n\tc.verifiedChains = hs.session.verifiedChains\n\tc.ocspResponse = hs.session.ocspResponse\n\t// Let the ServerHello SCTs override the session SCTs from the original\n\t// connection, if any are provided.\n\tif len(c.scts) == 0 && len(hs.session.scts) != 0 {\n\t\tc.scts = hs.session.scts","sourceCodeStart":925,"sourceCodeEnd":961,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client.go#L925-L961","documentation":"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.","triggerScenarios":"Server resuming a session but picking a different cipher suite; ticket corruption; server bug in resumption state binding.","commonSituations":"Misconfigured server resumption cache; rare.","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."],"exampleFix":"cfg := &tls.Config{SessionTicketsDisabled: true}","handlingStrategy":"fallback","validationCode":null,"typeGuard":"func isResumptionCipherMismatch(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"server resumed a session with a different cipher suite\")\n}","tryCatchPattern":"if _, err := tls.Dial(\"tcp\", addr, cfg); err != nil {\n    if isResumptionCipherMismatch(err) {\n        cfg.SessionTicketsDisabled = true\n        cfg.ClientSessionCache = nil\n        _, err = tls.Dial(\"tcp\", addr, cfg)\n    }\n}","preventionTips":["Rotate server ticket keys when cipher policies change.","Disable resumption against non-conformant servers."],"tags":["tls","session","resumption","cipher-suites","protocol"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}