{"record":{"id":"8b2a8cf6a5727b6c","repo":"golang/go","slug":"tls-server-chose-an-unconfigured-cipher-suite-8b2a8c","errorCode":null,"errorMessage":"tls: server chose an unconfigured cipher suite","messagePattern":"tls: server chose an unconfigured cipher suite","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/tls/handshake_client_tls13.go","lineNumber":211,"sourceCode":"\n\tif !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {\n\t\tc.sendAlert(alertIllegalParameter)\n\t\treturn errors.New(\"tls: server did not echo the legacy session ID\")\n\t}\n\n\tif hs.serverHello.compressionMethod != compressionNone {\n\t\tc.sendAlert(alertDecodeError)\n\t\treturn errors.New(\"tls: server sent non-zero legacy TLS compression method\")\n\t}\n\n\tselectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite)\n\tif hs.suite != nil && selectedSuite != hs.suite {\n\t\tc.sendAlert(alertIllegalParameter)\n\t\treturn errors.New(\"tls: server changed cipher suite after a HelloRetryRequest\")\n\t}\n\tif selectedSuite == nil {\n\t\tc.sendAlert(alertIllegalParameter)\n\t\treturn errors.New(\"tls: server chose an unconfigured cipher suite\")\n\t}\n\ths.suite = selectedSuite\n\tc.cipherSuite = hs.suite.id\n\n\treturn nil\n}\n\n// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility\n// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.\nfunc (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {\n\tif hs.c.quic != nil {\n\t\treturn nil\n\t}\n\tif hs.sentDummyCCS {\n\t\treturn nil\n\t}\n\ths.sentDummyCCS = true\n","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/tls/handshake_client_tls13.go#L193-L229","documentation":"Thrown in checkServerHelloOrHRR() when the server selects a TLS 1.3 cipher suite that the client did not offer. mutualCipherSuiteTLS13() returns nil because hs.serverHello.cipherSuite is not among hs.hello.cipherSuites.","triggerScenarios":"Triggered when mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite) returns nil. The client's offered cipher suite list does not contain the server's selection.","commonSituations":"Client tls.Config.CipherSuites is explicitly restricted to a subset that doesn't include the server's required suite. Server misconfigured to select a cipher suite not offered by the client. Client using an outdated Go version that doesn't support newer TLS 1.3 cipher suites the server requires.","solutions":["Check tls.Config.CipherSuites — if set, ensure it includes at least TLS_AES_128_GCM_SHA256 and TLS_AES_256_GCM_SHA384.","Leave CipherSuites nil (or empty) to use Go's default TLS 1.3 cipher suite set, which is recommended.","Verify the server's required cipher suites match what the client offers.","Update Go to a recent version for the latest cipher suite support."],"exampleFix":"// before — overly restrictive cipher suites\nconfig := &tls.Config{\n    CipherSuites: []uint16{tls.TLS_AES_256_GCM_SHA384},\n}\n\n// after — use defaults (recommended) or include common suites\nconfig := &tls.Config{\n    // CipherSuites nil = Go defaults, which include all TLS 1.3 suites\n}","handlingStrategy":"validation","validationCode":"// Validate cipher suite config before connecting\nfunc validateCipherSuites(config *tls.Config) error {\n    if config.CipherSuites == nil {\n        return nil // nil = Go defaults, always OK\n    }\n    // TLS 1.3 suites are not controlled by CipherSuites (ignored for 1.3),\n    // but if only 1.3 is offered, ensure the field isn't restrictive\n    hasTLS13 := false\n    for _, cs := range config.CipherSuites {\n        if cs == tls.TLS_AES_128_GCM_SHA256 || cs == tls.TLS_AES_256_GCM_SHA384 || cs == tls.TLS_CHACHA20_POLY1305_SHA256 {\n            hasTLS13 = true\n        }\n    }\n    if config.MinVersion >= tls.VersionTLS13 && !hasTLS13 {\n        return fmt.Errorf(\"TLS 1.3 required but no TLS 1.3 cipher suite in CipherSuites\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"conn, err := tls.Dial(\"tcp\", addr, config)\nif err != nil {\n    if strings.Contains(err.Error(), \"unconfigured cipher suite\") {\n        // Reset to defaults (nil) and retry\n        config.CipherSuites = nil\n        conn, err = tls.Dial(\"tcp\", addr, config)\n    }\n}","preventionTips":["Leave tls.Config.CipherSuites as nil to use Go's recommended defaults.","If restricting cipher suites, always include the three TLS 1.3 suites.","Document why custom cipher suites are needed and test against target servers."],"tags":["tls","go","tls13","cipher-suite","configuration"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}