hyperledger/fabric · error
TLSBinding failed
Error message
TLSBinding failed
What it means
During Auth(), the node computes a session binding hash and calls GetTLSSessionBinding to extract the TLS exporter-based binding value from the current gRPC stream context. If that call returns an error, it is wrapped with 'TLSBinding failed'. This means the TLS channel-binding could not be derived, typically because the connection is not a TLS connection or the TLS exporter is unavailable on the stream's context.
Source
Thrown at orderer/common/cluster/commauth.go:267
func (cs *NodeClientStream) Auth() error {
if cs.Signer == nil {
return errors.New("signer is nil")
}
payload := &orderer.NodeAuthRequest{
Version: cs.Version,
Timestamp: timestamppb.Now(),
FromId: cs.SourceNodeID,
ToId: cs.DestinationNodeID,
Channel: cs.Channel,
}
bindingFieldsHash := GetSessionBindingHash(payload)
tlsBinding, err := GetTLSSessionBinding(cs.StepClient.Context(), bindingFieldsHash)
if err != nil {
return errors.Wrap(err, "TLSBinding failed")
}
payload.SessionBinding = tlsBinding
asnSignFields, _ := asn1.Marshal(AuthRequestSignature{
Version: int64(payload.Version),
Timestamp: EncodeTimestamp(payload.Timestamp),
FromId: strconv.FormatUint(payload.FromId, 10),
ToId: strconv.FormatUint(payload.ToId, 10),
SessionBinding: payload.SessionBinding,
Channel: payload.Channel,
})
sig, err := cs.Signer.Sign(asnSignFields)
if err != nil {
return errors.Wrap(err, "signing failed")
}
payload.Signature = sig
stepRequest := &orderer.ClusterNodeServiceStepRequest{View on GitHub (pinned to 2736b63f8f)
Solutions
- Enable TLS on the orderer cluster communication (General.TLS.Enabled=true) so a TLS session exists to bind to.
- Ensure the grpc.ClientConn is created with proper TLS credentials (TLS credentials/transport security) for the cluster service.
- Inspect the wrapped cause in the error (errors.Wrap preserves it) and fix the underlying TLS exporter error it reports.
Example fix
// before (plaintext dial) conn, err := grpc.Dial(addr, grpc.WithInsecure()) // after cred, _ := credentials.NewClientTLSFromFile(certFile, serverNameOverride) conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(cred))
Defensive patterns
Strategy: validation
Validate before calling
// ensure the connection uses TLS before authenticating
if !tlsEnabledInConfig() {
return errors.New("cluster service requires TLS for session binding")
}
err := stream.Auth() Type guard
func isTLSSecured(ctx context.Context) bool {
_, ok := credentials.FromContext(ctx).(*tls.Credentials)
return ok
} Try / catch
if err := stream.Auth(); err != nil {
var cause error
if strings.Contains(err.Error(), "TLSBinding failed") {
errors.As(err, &cause)
log.Errorf("tls binding: %v", cause)
}
return err
} Prevention
- Keep General.TLS.Enabled=true for orderer cluster communication.
- Dial cluster peers with TLS transport credentials, never WithInsecure.
- Avoid TLS-terminating proxies between orderers that break channel binding.
When it happens
Trigger: Calling Auth() on a stream whose underlying gRPC connection is plaintext (TLS disabled), or where the security/exporter setup on the grpc.ClientConn does not provide the credentials needed by GetTLSSessionBinding; errors from the underlying TLS exporter call are wrapped here.
Common situations: Cluster configured with General.TLS.Enabled=false while mutual auth/session binding is expected; mismatched TLS settings between orderers; custom dial options that omit TLS credentials; proxy/load balancer stripping TLS.
Related errors
- failed to create new stream
- access denied, client identity wasn't supplied
- client didn't send a TLS certificate
- client claimed TLS hash doesn't match computed TLS hash from
- invalid request object
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/74f4257d1e03a69e.
Report an issue: GitHub.