golang/go · error
tls: unexpected server_name extension in server hello
Error message
tls: unexpected server_name extension in server hello
What it means
Thrown during TLS 1.3 ECH processing when ECH was accepted but the inner ClientHello had no server_name (SNI), yet the server's ServerHello includes a server_name acknowledgment. This is contradictory: if the inner hello didn't advertise a name, the server must not acknowledge one.
Source
Thrown at src/crypto/tls/handshake_client_tls13.go:113
if err != nil {
c.sendAlert(alertInternalError)
return err
}
acceptConfirmation := tls13.ExpandLabel(h, prk, "ech accept confirmation", confTranscript.Sum(nil), 8)
if subtle.ConstantTimeCompare(acceptConfirmation, hs.serverHello.random[len(hs.serverHello.random)-8:]) == 1 {
hs.hello = hs.echContext.innerHello
c.serverName = c.config.ServerName
hs.transcript = hs.echContext.innerTranscript
c.echAccepted = true
if hs.serverHello.encryptedClientHello != nil {
c.sendAlert(alertUnsupportedExtension)
return errors.New("tls: unexpected encrypted client hello extension in server hello despite ECH being accepted")
}
if hs.hello.serverName == "" && hs.serverHello.serverNameAck {
c.sendAlert(alertUnsupportedExtension)
return errors.New("tls: unexpected server_name extension in server hello")
}
} else {
hs.echContext.echRejected = true
}
}
if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
return err
}
c.buffering = true
if err := hs.processServerHello(); err != nil {
return err
}
if err := hs.sendDummyChangeCipherSpec(); err != nil {
return err
}
if err := hs.establishHandshakeKeys(); err != nil {View on GitHub (pinned to b6b368adc5)
Solutions
- Set config.ServerName to the real backend hostname when using ECH — the inner hello needs a valid SNI.
- Verify EncryptedClientHelloConfigList entries have correct DNS names matching config.ServerName.
- If ECH is not needed, remove config.EncryptedClientHelloConfigList to disable ECH.
- Ensure the ECH inner SNI and outer SNI are configured consistently.
Example fix
// before — ECH without inner SNI
config := &tls.Config{
EncryptedClientHelloConfigList: echList,
// ServerName missing!
}
// after — set the real hostname for the inner hello
config := &tls.Config{
ServerName: "backend.example.com",
EncryptedClientHelloConfigList: echList,
} Defensive patterns
Strategy: validation
Validate before calling
// Validate ECH config has a ServerName for the inner hello
func validateECHConfig(config *tls.Config) error {
if config.EncryptedClientHelloConfigList != nil && config.ServerName == "" {
return fmt.Errorf("ServerName must be set when using ECH — the inner hello needs an SNI")
}
return nil
} Try / catch
conn, err := tls.Dial("tcp", addr, config)
if err != nil {
if strings.Contains(err.Error(), "unexpected server_name extension in server hello") {
// Set ServerName for the inner hello and retry
config.ServerName = hostname
conn, err = tls.Dial("tcp", addr, config)
}
} Prevention
- Always set config.ServerName when using ECH.
- Validate ECH configuration before establishing connections.
- Test ECH inner hello SNI with DNS tools that resolve HTTPS/SVCB records.
When it happens
Trigger: Triggered when hs.hello.serverName is empty (the inner hello has no SNI) AND hs.serverHello.serverNameAck is true after ECH acceptance is confirmed. The client sends alertUnsupportedExtension.
Common situations: ECH inner hello configured without a ServerName because config.ServerName was left empty. Mismatch between the inner ClientHello's SNI and the server's response. Server bug in ECH server_name acknowledgment logic.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: unexpected encrypted client hello extension in server h
- tls: malformed encrypted client hello extension
- tls: unexpected encrypted client hello extension in serverHe
- tls: server sent encrypted client hello retry configs after
- tls: ML-DSA certificates require TLS 1.3
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/9061a1c135078d8d.
Report an issue: GitHub.