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

  1. Enable TLS on the orderer cluster communication (General.TLS.Enabled=true) so a TLS session exists to bind to.
  2. Ensure the grpc.ClientConn is created with proper TLS credentials (TLS credentials/transport security) for the cluster service.
  3. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/74f4257d1e03a69e. Report an issue: GitHub.