{"record":{"id":"cb8cf3ad1ed99a38","repo":"hyperledger/fabric","slug":"message-is-neither-a-submit-nor-a-consensus-reques","errorCode":null,"errorMessage":"message is neither a Submit nor a Consensus request","messagePattern":"message is neither a Submit nor a Consensus request","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/service.go","lineNumber":98,"sourceCode":"\t\treturn err\n\t}\n\n\texp.checkExpiration(time.Now(), extractChannel(request))\n\n\tif s.StepLogger.IsEnabledFor(zap.DebugLevel) {\n\t\tnodeName := commonNameFromContext(stream.Context())\n\t\ts.StepLogger.Debugf(\"Received message from %s(%s): %v\", nodeName, addr, requestAsString(request))\n\t}\n\n\tif submitReq := request.GetSubmitRequest(); submitReq != nil {\n\t\tnodeName := commonNameFromContext(stream.Context())\n\t\ts.Logger.Debugf(\"Received message from %s(%s): %v\", nodeName, addr, requestAsString(request))\n\t\treturn s.handleSubmit(submitReq, stream, addr)\n\t} else if consensusReq := request.GetConsensusRequest(); consensusReq != nil {\n\t\treturn s.Dispatcher.DispatchConsensus(stream.Context(), request.GetConsensusRequest())\n\t}\n\n\treturn errors.Errorf(\"message is neither a Submit nor a Consensus request\")\n}\n\nfunc (s *Service) handleSubmit(request *orderer.SubmitRequest, stream StepStream, addr string) error {\n\terr := s.Dispatcher.DispatchSubmit(stream.Context(), request)\n\tif err != nil {\n\t\ts.Logger.Warningf(\"Handling of Submit() from %s failed: %v\", addr, err)\n\t\treturn err\n\t}\n\treturn err\n}\n\nfunc (s *Service) initializeExpirationCheck(stream orderer.Cluster_StepServer, endpoint, nodeName string) *certificateExpirationCheck {\n\treturn &certificateExpirationCheck{\n\t\tminimumExpirationWarningInterval: s.MinimumExpirationWarningInterval,\n\t\texpirationWarningThreshold:       s.CertExpWarningThreshold,\n\t\texpiresAt:                        expiresAt(stream),\n\t\tendpoint:                         endpoint,\n\t\tnodeName:                         nodeName,","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/service.go#L80-L116","documentation":"The cluster Step service's handleMessage expects every incoming request on the stream to be either a SubmitRequest (forwarded transactions) or a ConsensusRequest (Raft messages); anything else produces this error and aborts handling. It guards the Step RPC against malformed or unsupported message types.","triggerScenarios":"A client sends a StepRequest whose inner request has neither SubmitRequest nor ConsensusRequest populated; a Fabric client of a different version sends an unexpected message type over the cluster Step stream.","commonSituations":"Fabric version incompatibility between ordering nodes (new message types unknown to the receiver); a misbehaving or buggy custom client calling Step directly; corrupted gRPC payloads after proxy/LB interference with streaming.","solutions":["Ensure all ordering nodes run the same compatible Fabric version","Check what client/peer is sending the malformed Step requests in the logs (addr is logged) and fix or upgrade it","Verify no intermediate proxy is corrupting or rewriting gRPC streams","Confirm applications use Broadcast/Deliver APIs, not raw Step, for transaction submission"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"switch {\ncase req.GetSubmitRequest() != nil: // Submit path\ncase req.GetConsensusRequest() != nil: // Consensus path\ndefault:\n    return errors.New(\"message is neither a Submit nor a Consensus request\")\n}","typeGuard":"func isKnownClusterRequest(req *orderer.Request) bool {\n    return req.GetSubmitRequest() != nil || req.GetConsensusRequest() != nil\n}","tryCatchPattern":"err := service.Step(stream, request)\nif err != nil && strings.Contains(err.Error(), \"neither a Submit nor a Consensus request\") {\n    // sender sends unsupported type: log addr, drop or close stream\n    return stream.Close()\n}","preventionTips":["Run identical Fabric versions on all cluster members","Only call Step via the built-in cluster/etcdraft plumbing","Keep load balancers gRPC-stream-transparent","Validate request payloads before sending on the Step stream"],"tags":["fabric","orderer","grpc","protocol"],"backgroundTag":"unsupported-request-type","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"}