{"record":{"id":"da2a039db621eb45","repo":"hyperledger/fabric","slug":"failed-to-unmarshal-steprequest-payload-to-raft-me","errorCode":null,"errorMessage":"failed to unmarshal StepRequest payload to Raft Message: %s","messagePattern":"failed to unmarshal StepRequest payload to Raft Message: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/chain.go","lineNumber":512,"sourceCode":"\n\tselect {\n\tcase <-c.doneC:\n\t\treturn errors.Errorf(\"chain is stopped\")\n\tdefault:\n\t}\n\n\treturn nil\n}\n\n// Consensus passes the given ConsensusRequest message to the raft.Node instance\nfunc (c *Chain) Consensus(req *orderer.ConsensusRequest, sender uint64) error {\n\tif err := c.isRunning(); err != nil {\n\t\treturn err\n\t}\n\n\tstepMsg := &raftpb.Message{}\n\tif err := proto.Unmarshal(req.GetPayload(), stepMsg); err != nil {\n\t\treturn fmt.Errorf(\"failed to unmarshal StepRequest payload to Raft Message: %s\", err)\n\t}\n\n\tif stepMsg.GetTo() != c.raftID {\n\t\tc.logger.Warnf(\"Received msg to %d, my ID is probably wrong due to out of date, cowardly halting\", stepMsg.GetTo())\n\t\tc.halt()\n\t\treturn nil\n\t}\n\n\tif err := c.Node.Step(context.TODO(), stepMsg); err != nil {\n\t\treturn fmt.Errorf(\"failed to process Raft Step message: %s\", err)\n\t}\n\n\tif len(req.GetMetadata()) == 0 || atomic.LoadUint64(&c.lastKnownLeader) != sender { // ignore metadata from non-leader\n\t\treturn nil\n\t}\n\n\tclusterMetadata := &etcdraft.ClusterMetadata{}\n\tif err := proto.Unmarshal(req.GetMetadata(), clusterMetadata); err != nil {","sourceCodeStart":494,"sourceCodeEnd":530,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/chain.go#L494-L530","documentation":"Step is the entry point for raft consensus messages (raftpb.Message) delivered over the cluster RPC. If the request payload cannot be protobuf-unmarshaled into a raft Message, the chain returns this formatted error. It indicates the sender produced an invalid or incompatible payload.","triggerScenarios":"A remote orderer sends a ConsensusRequest whose Payload is empty, truncated, or not a valid serialized raftpb.Message — e.g., mixed Fabric versions with incompatible wire payloads, a proxy mangling bytes, or a misbehaving/compromised sender.","commonSituations":"Rolling upgrades where old and new orderers disagree on payload encoding; network middleware (service mesh, proxy) corrupting gRPC bodies; a wrong node receiving cluster traffic intended for another protocol.","solutions":["Verify all orderers in the network run compatible Fabric versions; complete rolling upgrades before relying on new channels.","Inspect which sender produced the malformed payload from logs/metrics and check that node's health and version.","Check for proxies or service meshes in the cluster port path that could alter gRPC frames; bypass or fix them.","Confirm cluster TLS mutual auth so only legitimate orderers can send Step requests."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"stepMsg := &raftpb.Message{}\nif len(req.GetPayload()) == 0 {\n    return errors.New(\"rejecting empty Step payload from sender\")\n}\nif err := proto.Unmarshal(req.GetPayload(), stepMsg); err != nil {\n    return fmt.Errorf(\"invalid payload from %s: %s\", sender, err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep all orderers on compatible Fabric versions","Enforce mutual TLS on cluster ports so only real orderers send Step","Audit proxy/service-mesh configs for gRPC body mutation"],"tags":["orderer","etcdraft","protobuf","grpc"],"backgroundTag":"protobuf-unmarshal-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"}