golang/go · error

tls: server chose an unconfigured cipher suite

Error message

tls: server chose an unconfigured cipher suite

What it means

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.

Source

Thrown at src/crypto/tls/handshake_client_tls13.go:211

	if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
		c.sendAlert(alertIllegalParameter)
		return errors.New("tls: server did not echo the legacy session ID")
	}

	if hs.serverHello.compressionMethod != compressionNone {
		c.sendAlert(alertDecodeError)
		return errors.New("tls: server sent non-zero legacy TLS compression method")
	}

	selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite)
	if hs.suite != nil && selectedSuite != hs.suite {
		c.sendAlert(alertIllegalParameter)
		return errors.New("tls: server changed cipher suite after a HelloRetryRequest")
	}
	if selectedSuite == nil {
		c.sendAlert(alertIllegalParameter)
		return errors.New("tls: server chose an unconfigured cipher suite")
	}
	hs.suite = selectedSuite
	c.cipherSuite = hs.suite.id

	return nil
}

// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
	if hs.c.quic != nil {
		return nil
	}
	if hs.sentDummyCCS {
		return nil
	}
	hs.sentDummyCCS = true

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Check tls.Config.CipherSuites — if set, ensure it includes at least TLS_AES_128_GCM_SHA256 and TLS_AES_256_GCM_SHA384.
  2. Leave CipherSuites nil (or empty) to use Go's default TLS 1.3 cipher suite set, which is recommended.
  3. Verify the server's required cipher suites match what the client offers.
  4. Update Go to a recent version for the latest cipher suite support.

Example fix

// before — overly restrictive cipher suites
config := &tls.Config{
    CipherSuites: []uint16{tls.TLS_AES_256_GCM_SHA384},
}

// after — use defaults (recommended) or include common suites
config := &tls.Config{
    // CipherSuites nil = Go defaults, which include all TLS 1.3 suites
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate cipher suite config before connecting
func validateCipherSuites(config *tls.Config) error {
    if config.CipherSuites == nil {
        return nil // nil = Go defaults, always OK
    }
    // TLS 1.3 suites are not controlled by CipherSuites (ignored for 1.3),
    // but if only 1.3 is offered, ensure the field isn't restrictive
    hasTLS13 := false
    for _, cs := range config.CipherSuites {
        if cs == tls.TLS_AES_128_GCM_SHA256 || cs == tls.TLS_AES_256_GCM_SHA384 || cs == tls.TLS_CHACHA20_POLY1305_SHA256 {
            hasTLS13 = true
        }
    }
    if config.MinVersion >= tls.VersionTLS13 && !hasTLS13 {
        return fmt.Errorf("TLS 1.3 required but no TLS 1.3 cipher suite in CipherSuites")
    }
    return nil
}

Try / catch

conn, err := tls.Dial("tcp", addr, config)
if err != nil {
    if strings.Contains(err.Error(), "unconfigured cipher suite") {
        // Reset to defaults (nil) and retry
        config.CipherSuites = nil
        conn, err = tls.Dial("tcp", addr, config)
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/8b2a8cf6a5727b6c. Report an issue: GitHub.