{"record":{"id":"729b00a94a9643ab","repo":"hyperledger/fabric","slug":"invalid-request-object","errorCode":null,"errorMessage":"invalid request object","messagePattern":"invalid request object","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/clusterservice.go","lineNumber":125,"sourceCode":"\t}()\n\n\tfor {\n\t\terr := s.handleMessage(stream, addr, exp, authReq.Channel, authReq.FromId, streamID)\n\t\tif err == io.EOF {\n\t\t\ts.Logger.Debugf(\"%s(%s) disconnected\", commonName, addr)\n\t\t\treturn nil\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// Else, no error occurred, so we continue to the next iteration\n\t}\n}\n\nfunc (s *ClusterService) VerifyAuthRequest(stream orderer.ClusterNodeService_StepServer, request *orderer.ClusterNodeServiceStepRequest) (*orderer.NodeAuthRequest, error) {\n\tauthReq := request.GetNodeAuthrequest()\n\tif authReq == nil {\n\t\treturn nil, errors.New(\"invalid request object\")\n\t}\n\n\tbindingFieldsHash := GetSessionBindingHash(authReq)\n\n\ttlsBinding, err := GetTLSSessionBinding(stream.Context(), bindingFieldsHash)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"session binding read failed\")\n\t}\n\n\tif !bytes.Equal(tlsBinding, authReq.SessionBinding) {\n\t\treturn nil, errors.New(\"session binding mismatch\")\n\t}\n\n\tmsg, err := asn1.Marshal(AuthRequestSignature{\n\t\tVersion:        int64(authReq.Version),\n\t\tTimestamp:      EncodeTimestamp(authReq.Timestamp),\n\t\tFromId:         strconv.FormatUint(authReq.FromId, 10),\n\t\tToId:           strconv.FormatUint(authReq.ToId, 10),","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/clusterservice.go#L107-L143","documentation":"ClusterService.VerifyAuthRequest authenticates node-to-node (cluster) Step requests. It expects the request to carry a NodeAuthRequest oneof (request.GetNodeAuthrequest()). This error means the incoming request did not contain the authentication message at all, so no signature/TLS-binding verification can proceed.","triggerScenarios":"A node (or step-client such as osnadmin/consenter tooling) sends a StepRequest whose oneof payload is the Submit/SubmitRequest variant instead of NodeAuthrequest, or an empty request; a peer running older Fabric code that predates cluster node authentication talking to a newer orderer.","commonSituations":"Version skew between ordering nodes or between peer and orderer after an upgrade; misconfigured cluster senders; a load balancer or proxy stripping/replacing the gRPC message; manual gRPC testing that omits the auth field.","solutions":["Upgrade all nodes to a Fabric version that supports cluster node authentication (v3.x era consensus changes) so senders populate NodeAuthrequest.","Ensure the Step client sets the oneof to NodeAuthrequest first (authentication handshake) before Submit requests.","Check for intermediaries (proxies, service meshes) rewriting or dropping gRPC message fields.","Reproduce with a minimal gRPC client and inspect which oneof variant is actually set before sending."],"exampleFix":"// before\nreq := &orderer.StepRequest{Payload: &orderer.StepRequest_SubmitRequest{...}} // auth missing\n// after\nreq := &orderer.StepRequest{Payload: &orderer.StepRequest_NodeAuthrequest{NodeAuthrequest: authReq}}","handlingStrategy":"try-catch","validationCode":"if req.GetNodeAuthrequest() == nil {\n    return errors.New(\"StepRequest must carry the NodeAuthrequest oneof variant\")\n}","typeGuard":"func isAuthRequest(req *orderer.ClusterNodeServiceStepRequest) bool {\n    return req != nil && req.GetNodeAuthrequest() != nil\n}","tryCatchPattern":"authReq, err := svc.VerifyAuthRequest(stream, request)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid request object\") {\n        // sender is not populating the auth oneof — check version/config\n    }\n    return err\n}","preventionTips":["Run homogeneous Fabric versions across cluster nodes and peers","Ensure step clients perform the auth handshake before Submit requests","Audit proxies/service meshes for gRPC message rewriting","Add integration tests covering node-to-node Step authentication"],"tags":["fabric","orderer","grpc","authentication","cluster"],"backgroundTag":"grpc-auth-handshake-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"}