golang/go · error
tls: server chose an unconfigured cipher suite
Error message
tls: server chose an unconfigured cipher suite
What it means
pickCipherSuite calls mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite). It walks the client's offered list and returns nil if the server-chosen ID is not present. A conformant TLS server must pick a suite the client offered; selecting anything else is a protocol violation and aborts the handshake with alertHandshakeFailure.
Source
Thrown at src/crypto/tls/handshake_client.go:634
}
if err := hs.readFinished(c.serverFinished[:]); err != nil {
return err
}
}
if err := hs.saveSessionTicket(); err != nil {
return err
}
c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
c.isHandshakeComplete.Store(true)
return nil
}
func (hs *clientHandshakeState) pickCipherSuite() error {
if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {
hs.c.sendAlert(alertHandshakeFailure)
return errors.New("tls: server chose an unconfigured cipher suite")
}
hs.c.cipherSuite = hs.suite.id
return nil
}
func (hs *clientHandshakeState) doFullHandshake() error {
c := hs.c
msg, err := c.readHandshake(&hs.finishedHash)
if err != nil {
return err
}
certMsg, ok := msg.(*certificateMsg)
if !ok || len(certMsg.certificates) == 0 {
c.sendAlert(alertUnexpectedMessage)
return unexpectedMessageError(certMsg, msg)
}View on GitHub (pinned to b6b368adc5)
Solutions
- Leave Config.CipherSuites nil so Go uses its curated default suite list (includes modern AEAD TLS 1.2 and TLS 1.3 suites).
- If you must pin, include at least one AEAD suite the server speaks: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 / TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 / TLS 1.3 suites.
- Update the server's cipher configuration to offer suites the client supports.
- Re-evaluate whether the FIPS build is appropriate for this peer.
Example fix
// before: overly restrictive pinning
cfg := &tls.Config{CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}}
// after: trust Go's defaults
cfg := &tls.Config{} Defensive patterns
Strategy: validation
Validate before calling
// Validate that your pinned CipherSuites overlap with the defaults Go offers,
// and include at least one AEAD suite.
func validateCipherSuites(cs []uint16) error {
if len(cs) == 0 { return nil }
allowed := map[uint16]bool{
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: true,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true,
tls.TLS_AES_128_GCM_SHA256: true,
tls.TLS_AES_256_GCM_SHA384: true,
tls.TLS_CHACHA20_POLY1305_SHA256: true,
}
for _, c := range cs {
if !allowed[c] { return fmt.Errorf("unsupported/weak cipher suite: %x", c) }
}
return nil
} Type guard
func isUnconfiguredCipherSuite(err error) bool {
return err != nil && strings.Contains(err.Error(), "server chose an unconfigured cipher suite")
} Try / catch
if _, err := tls.Dial("tcp", addr, cfg); err != nil {
if isUnconfiguredCipherSuite(err) {
// Retry once with the default suite list.
cfg.CipherSuites = nil
_, err = tls.Dial("tcp", addr, cfg)
}
} Prevention
- Leave Config.CipherSuites nil unless you have a hard requirement.
- If pinning, always include at least one AEAD suite the server speaks.
- Re-evaluate FIPS builds when peers change.
When it happens
Trigger: Config.CipherSuites is set to a restrictive list that has no overlap with what the server selected; FIPS-only Go build (GOEXPERIMENT=fips140) strips non-approved suites; server is misconfigured or being manipulated; server picked a disabled/weak suite like TLS_RSA_WITH_3DES_EDE_CBC_SHA.
Common situations: Pinning cipher suites too narrowly; FIPS 140-3 module build connecting to a server expecting non-approved suites; old server that only offers RC4/3DES; client and server on disjoint crypto policies.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: client sent an unexpected quic_transport_parameters ext
- tls: missing signature_algorithms from TLS 1.2 peer
- tls: peer doesn't support any of the certificate's signature
- connection doesn't support Ed25519
- tls: invalid outer extensions
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/cc0f2aa2a6091183.
Report an issue: GitHub.