golang/go · error
tls: invalid or missing PSK binders
Error message
tls: invalid or missing PSK binders
What it means
RFC 8446 §4.2.11 requires the number of PSK identities to equal the number of binders, in order. If len(pskIdentities) != len(pskBinders), the ClientHello is malformed; the server sends illegal_parameter.
Source
Thrown at src/crypto/tls/handshake_server_tls13.go:312
if c.config.SessionTicketsDisabled {
return nil
}
modeOK := false
for _, mode := range hs.clientHello.pskModes {
if mode == pskModeDHE {
modeOK = true
break
}
}
if !modeOK {
return nil
}
if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: invalid or missing PSK binders")
}
if len(hs.clientHello.pskIdentities) == 0 {
return nil
}
for i, identity := range hs.clientHello.pskIdentities {
if i >= maxClientPSKIdentities {
break
}
var sessionState *SessionState
if c.config.UnwrapSession != nil {
var err error
sessionState, err = c.config.UnwrapSession(identity.label, c.connectionStateLocked())
if err != nil {
return err
}
if sessionState == nil {View on GitHub (pinned to b6b368adc5)
Solutions
- Ensure each PSK identity has exactly one corresponding binder, in the same order
- Use a compliant TLS library to construct the pre_shared_key extension rather than building it by hand
Example fix
// before
identities = []pskIdentity{a, b, c}
binders = [][]byte{ba, bb} // missing c
// after
identities = []pskIdentity{a, b, c}
binders = [][]byte{ba, bb, bc} Defensive patterns
Strategy: validation
Validate before calling
// Client-side: before sending, assert identity/binder counts match.
if len(pskIdentities) != len(pskBinders) {
return fmt.Errorf("psk mismatch: %d identities vs %d binders", len(pskIdentities), len(pskBinders))
} Try / catch
if err := tlsConn.Handshake(); err != nil {
if strings.Contains(err.Error(), "invalid or missing PSK binders") {
log.Printf("malformed pre_shared_key from %v", remote)
}
c.Close()
return
} Prevention
- Always append a binder for every identity you add, in order
- Use a compliant TLS library to construct pre_shared_key rather than hand-building it
When it happens
Trigger: Client sends 3 identities but 2 binders, or any count mismatch. Occurs when a ClientHello is constructed with mismatched identity/binder lists.
Common situations: Buggy session-resumption code that appends an identity without its binder; fuzzers; attackers hand-crafting ClientHellos.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- tls: client used the legacy version field to negotiate TLS 1
- tls: TLS 1.3 client supports illegal compression methods
- tls: initial handshake had non-empty renegotiation extension
- tls: server selected an invalid PSK
- tls: server selected an invalid PSK and cipher suite pair
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/6a3a3eceda133a8b.
Report an issue: GitHub.