hyperledger/fabric · error
session binding mismatch
Error message
session binding mismatch
What it means
After computing the expected TLS binding, VerifyAuthRequest compares it byte-for-byte with authReq.SessionBinding supplied by the client. This error means the client-claimed binding does not match the actual TLS session, i.e. the request may be replayed or sent over a different connection than the one that signed it — an authentication security check.
Source
Thrown at orderer/common/cluster/clusterservice.go:136
// Else, no error occurred, so we continue to the next iteration
}
}
func (s *ClusterService) VerifyAuthRequest(stream orderer.ClusterNodeService_StepServer, request *orderer.ClusterNodeServiceStepRequest) (*orderer.NodeAuthRequest, error) {
authReq := request.GetNodeAuthrequest()
if authReq == nil {
return nil, errors.New("invalid request object")
}
bindingFieldsHash := GetSessionBindingHash(authReq)
tlsBinding, err := GetTLSSessionBinding(stream.Context(), bindingFieldsHash)
if err != nil {
return nil, errors.Wrap(err, "session binding read failed")
}
if !bytes.Equal(tlsBinding, authReq.SessionBinding) {
return nil, errors.New("session binding mismatch")
}
msg, err := asn1.Marshal(AuthRequestSignature{
Version: int64(authReq.Version),
Timestamp: EncodeTimestamp(authReq.Timestamp),
FromId: strconv.FormatUint(authReq.FromId, 10),
ToId: strconv.FormatUint(authReq.ToId, 10),
SessionBinding: tlsBinding,
Channel: authReq.Channel,
})
if err != nil {
return nil, errors.Wrap(err, "ASN encoding failed")
}
membership := s.MembershipByChannel[authReq.Channel]
if membership == nil {
return nil, errors.Errorf("channel %s not found in config", authReq.Channel)
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the client computes and sends a fresh NodeAuthRequest per TLS connection, re-deriving GetSessionBindingHash from the live connection rather than reusing a cached value.
- Upgrade both peers and orderers to matching Fabric versions so the binding-hash algorithm and fields agree.
- Check that the TLS client certificate used for signing is the same one presented on the connection.
- If using custom/proxied transports, make sure the original TLS session identity reaches the orderer unchanged.
Example fix
// before authReq := cachedAuthReq // reused across connections -> binding mismatch // after authReq := cluster.NewAuthRequest(conn, signer) // computed from current TLS session
Defensive patterns
Strategy: validation
Validate before calling
// client side: derive the binding from the LIVE connection, never cache it
bindingHash := cluster.GetSessionBindingHash(authReq)
tlsBinding, err := cluster.GetTLSSessionBinding(ctx, bindingHash)
if err != nil { return err }
if !bytes.Equal(tlsBinding, authReq.SessionBinding) {
return errors.New("client-side binding mismatch: recompute per connection")
} Try / catch
_, err := svc.VerifyAuthRequest(stream, request)
if err != nil && strings.Contains(err.Error(), "session binding mismatch") {
// do NOT retry with the same auth request; regenerate it on a fresh connection
return status.Error(codes.Unauthenticated, "stale session binding: re-authenticate")
} Prevention
- Never cache NodeAuthRequests across TLS connections (replay protection is by design)
- Match Fabric versions so binding hash fields agree on both ends
- Sign and send over the same TLS session the binding was computed from
- Treat repeated mismatches as a security signal and audit for replay attempts
When it happens
Trigger: A client caches/reuses an auth request (and its binding) across new TLS connections; the client computes GetSessionBindingHash with different fields than the server; clock/connection differences such that the binding hash inputs diverge.
Common situations: Connection pooling that reuses stale authenticated requests on fresh TLS sessions; replay attempts (legitimate or malicious); differing Fabric versions hashing different fields; wrong channel/endpoint config causing the client to bind against a different context.
Related errors
- session binding read failed
- failed to create new stream
- invalid request object
- invalid certificate DER
- TLSBinding failed
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/a08af51471278b62.
Report an issue: GitHub.