{"record":{"id":"74f4257d1e03a69e","repo":"hyperledger/fabric","slug":"tlsbinding-failed","errorCode":null,"errorMessage":"TLSBinding failed","messagePattern":"TLSBinding failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/commauth.go","lineNumber":267,"sourceCode":"\nfunc (cs *NodeClientStream) Auth() error {\n\tif cs.Signer == nil {\n\t\treturn errors.New(\"signer is nil\")\n\t}\n\n\tpayload := &orderer.NodeAuthRequest{\n\t\tVersion:   cs.Version,\n\t\tTimestamp: timestamppb.Now(),\n\t\tFromId:    cs.SourceNodeID,\n\t\tToId:      cs.DestinationNodeID,\n\t\tChannel:   cs.Channel,\n\t}\n\n\tbindingFieldsHash := GetSessionBindingHash(payload)\n\n\ttlsBinding, err := GetTLSSessionBinding(cs.StepClient.Context(), bindingFieldsHash)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"TLSBinding failed\")\n\t}\n\tpayload.SessionBinding = tlsBinding\n\n\tasnSignFields, _ := asn1.Marshal(AuthRequestSignature{\n\t\tVersion:        int64(payload.Version),\n\t\tTimestamp:      EncodeTimestamp(payload.Timestamp),\n\t\tFromId:         strconv.FormatUint(payload.FromId, 10),\n\t\tToId:           strconv.FormatUint(payload.ToId, 10),\n\t\tSessionBinding: payload.SessionBinding,\n\t\tChannel:        payload.Channel,\n\t})\n\tsig, err := cs.Signer.Sign(asnSignFields)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"signing failed\")\n\t}\n\n\tpayload.Signature = sig\n\tstepRequest := &orderer.ClusterNodeServiceStepRequest{","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/commauth.go#L249-L285","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (plaintext dial)\nconn, err := grpc.Dial(addr, grpc.WithInsecure())\n// after\ncred, _ := credentials.NewClientTLSFromFile(certFile, serverNameOverride)\nconn, err := grpc.Dial(addr, grpc.WithTransportCredentials(cred))","handlingStrategy":"validation","validationCode":"// ensure the connection uses TLS before authenticating\nif !tlsEnabledInConfig() {\n    return errors.New(\"cluster service requires TLS for session binding\")\n}\nerr := stream.Auth()","typeGuard":"func isTLSSecured(ctx context.Context) bool {\n    _, ok := credentials.FromContext(ctx).(*tls.Credentials)\n    return ok\n}","tryCatchPattern":"if err := stream.Auth(); err != nil {\n    var cause error\n    if strings.Contains(err.Error(), \"TLSBinding failed\") {\n        errors.As(err, &cause)\n        log.Errorf(\"tls binding: %v\", cause)\n    }\n    return err\n}","preventionTips":["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."],"tags":["tls","fabric","authentication","grpc"],"backgroundTag":"tls-channel-binding-failed","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}