{"record":{"id":"395f443d883f4f6e","repo":"hyperledger/fabric","slug":"failed-to-unmarshal-clustermetadata-s","errorCode":null,"errorMessage":"failed to unmarshal ClusterMetadata: %s","messagePattern":"failed to unmarshal ClusterMetadata: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/etcdraft/chain.go","lineNumber":531,"sourceCode":"\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 {\n\t\treturn errors.Errorf(\"failed to unmarshal ClusterMetadata: %s\", err)\n\t}\n\n\tc.Metrics.ActiveNodes.Set(float64(len(clusterMetadata.GetActiveNodes())))\n\tc.ActiveNodes.Store(clusterMetadata.GetActiveNodes())\n\tc.logger.Infof(\"Store ActiveNodes %+v\", clusterMetadata.GetActiveNodes())\n\n\treturn nil\n}\n\n// Submit forwards the incoming request to:\n// - the local run goroutine if this is leader\n// - the actual leader via the transport mechanism\n// The call fails if there's no leader elected yet.\nfunc (c *Chain) Submit(req *orderer.SubmitRequest, sender uint64) error {\n\tif err := c.isRunning(); err != nil {\n\t\tc.Metrics.ProposalFailures.Add(1)\n\t\treturn err\n\t}","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/chain.go#L513-L549","documentation":"This error is returned when the chain receives a StepRequest whose metadata payload cannot be deserialized into an etcdraft.ClusterMetadata protobuf. The metadata is sent by the Raft leader to inform followers of active nodes membership; if the bytes are corrupt, truncated, or not valid protobuf, this error is thrown.","triggerScenarios":"A leader node broadcasts cluster metadata (active nodes) to followers, but the req.GetMetadata() bytes fail proto.Unmarshal — e.g. version mismatch between ordering nodes, corrupted gRPC payload, or a custom proxy mutating the message.","commonSituations":"Rolling upgrades where nodes run different Hyperledger Fabric versions with incompatible metadata encoding; a misconfigured intermediary/proxy that mangles protobuf bytes; manually edited consensus metadata in the channel config.","solutions":["Verify all ordering nodes run the same Fabric binary version (docker image tags match).","Inspect the channel config consensus metadata with 'configtxlator' to confirm it is valid protobuf for etcdraft.Metadata.","Capture the inner error from the message to identify whether it is a wire-format or field mismatch.","Re-produce the config update: regenerate the channel config block from a clean genesis config and restart the ordering service."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["hyperledger-fabric","etcdraft","protobuf","unmarshal"],"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"}