{"record":{"id":"95e7e3c8829a22b0","repo":"golang/go","slug":"tls-session-supported-extended-master-secret-but","errorCode":null,"errorMessage":"tls: session supported extended_master_secret but client does not","messagePattern":"tls: session supported extended_master_secret but client does not","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_server.go","lineNumber":536,"sourceCode":"\t}\n\topts := x509.VerifyOptions{\n\t\tCurrentTime: c.config.time(),\n\t\tRoots:       c.config.ClientCAs,\n\t\tKeyUsages:   []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},\n\t}\n\tif sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&\n\t\t!anyValidVerifiedChain(sessionState.verifiedChains, opts) {\n\t\treturn nil\n\t}\n\n\t// RFC 7627, Section 5.3\n\tif !sessionState.extMasterSecret && hs.clientHello.extendedMasterSecret {\n\t\treturn nil\n\t}\n\tif sessionState.extMasterSecret && !hs.clientHello.extendedMasterSecret {\n\t\t// Aborting is somewhat harsh, but it's a MUST and it would indicate a\n\t\t// weird downgrade in client capabilities.\n\t\treturn errors.New(\"tls: session supported extended_master_secret but client does not\")\n\t}\n\tif !sessionState.extMasterSecret && fips140tls.Required() {\n\t\tif fips140ems.Value() != \"0\" {\n\t\t\t// FIPS 140-3 requires the use of Extended Master Secret.\n\t\t\treturn nil\n\t\t}\n\t\tfips140ems.IncNonDefault()\n\t}\n\n\tc.peerCertificates = sessionState.peerCertificates\n\tc.ocspResponse = sessionState.ocspResponse\n\tc.scts = sessionState.scts\n\tc.verifiedChains = sessionState.verifiedChains\n\tc.extMasterSecret = sessionState.extMasterSecret\n\ths.sessionState = sessionState\n\ths.suite = suite\n\tc.curveID = sessionState.curveID\n\tc.didResume = true","sourceCodeStart":518,"sourceCodeEnd":554,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_server.go#L518-L554","documentation":"During session resumption the server found that the cached session used extended_master_secret (RFC 7627) but the current ClientHello does not advertise it. This is an EMS downgrade — the spec mandates aborting because silently accepting would weaken the security of the resumed session.","triggerScenarios":"In the server's session-resumption path: sessionState.extMasterSecret is true but hs.clientHello.extendedMasterSecret is false. The session was originally negotiated with EMS; the new ClientHello dropped the extension.","commonSituations":"A client that previously connected with EMS but is now configured (or downgraded) to omit it — possibly due to a library change, a middlebox stripping the extension, or a different client process reusing a cached ticket. Also a possible rollback attack vector.","solutions":["Ensure the client consistently advertises extended_master_secret on every connection (most modern stacks do by default).","Investigate middleware/proxies that strip EMS — they create exactly this downgrade.","Invalidate and rotate session tickets if the client legitimately changed capabilities, so stale EMS-flagged tickets are not reused.","Update the client TLS library to a version that always offers EMS."],"exampleFix":"// Most modern Go/Rust/OpenSSL clients always advertise EMS.\n// If using a custom stack, ensure the extension is present:\n//   - OpenSSL: enabled by default since 1.1.0\n//   - Go: always sent for TLS 1.2\n//   - Do not set any 'disable_extended_master_secret' flags","handlingStrategy":"validation","validationCode":"// Client: always advertise extended_master_secret for TLS 1.2.\n// Go clients do this automatically. If using a custom stack, include the\n// extension and never disable it for sessions previously negotiated with EMS.","typeGuard":null,"tryCatchPattern":"// Server: catch during resumption and force a full handshake instead.\nif err != nil && strings.Contains(err.Error(), \"session supported extended_master_secret but client does not\") {\n    // invalidate cached ticket and require full handshake\n    sessionCache.Put(sessionKey, nil)\n}","preventionTips":["Always advertise EMS consistently across all client connections.","Rotate session tickets when client capabilities legitimately change.","Audit middleboxes for EMS-stripping behavior."],"tags":["tls","server-handshake","extended-master-secret","rfc-7627","session-resumption","downgrade"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}