{"record":{"id":"55cbb49407b5385c","repo":"hyperledger/fabric","slug":"chain-is-not-started","errorCode":null,"errorMessage":"chain is not started","messagePattern":"chain is not started","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"orderer/consensus/etcdraft/chain.go","lineNumber":492,"sourceCode":"\t\tc.statusReportMutex.Lock()\n\t\tdefer c.statusReportMutex.Unlock()\n\n\t\t// If the haltCallback registers the chain in to the inactive chain registry (i.e., system channel exists) then\n\t\t// this is the correct consensusRelation. If the haltCallback transfers responsibility to a follower.Chain, then\n\t\t// this chain is about to be GC anyway. The new follower.Chain replacing this one will report the correct\n\t\t// StatusReport.\n\t\tc.consensusRelation = types.ConsensusRelationConfigTracker\n\t}\n\n\t// active nodes metric shouldn't be frozen once a channel is stopped.\n\tc.Metrics.ActiveNodes.Set(float64(0))\n}\n\nfunc (c *Chain) isRunning() error {\n\tselect {\n\tcase <-c.startC:\n\tdefault:\n\t\treturn errors.Errorf(\"chain is not started\")\n\t}\n\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{}","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/etcdraft/chain.go#L474-L510","documentation":"isRunning is a precondition check used by Step/Submit-style entry points. It performs a non-blocking receive on startC: if the chain's Start has not yet run, it returns 'chain is not started'. This prevents interacting with the raft node before it exists.","triggerScenarios":"Calling Chain.Step (consensus message handling) or Submit before the chain's Start() go-routine has initialized submitC/startC — e.g., consensus messages arriving from other orderers immediately after chain registration but before start completes.","commonSituations":"A burst of raft Step messages arriving from peers at exactly chain-creation time; onboarding a channel while other orderers already gossip consensus messages; races during dynamic channel creation.","solutions":["Retry after a short delay — this is a transient startup race; the chain will start momentarily.","Verify chain start-up is not blocked by earlier errors in the orderer log (WAL restore, storage creation) that leave the chain never-started.","Ensure the orderer joined the channel properly so Start() is invoked; a channel registered but never started indicates a lifecycle bug or failed creation.","If persistent, restart the orderer and check for errors preventing the raft chain from starting."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := chain.WaitReady(); err != nil {\n    if strings.Contains(err.Error(), \"chain is not started\") {\n        time.Sleep(100 * time.Millisecond)\n        return chain.WaitReady() // transient startup race\n    }\n    return err\n}","preventionTips":["Expect transient not-started errors during channel onboarding","Ensure chain Start() is invoked immediately after registration","Check startup logs if the error persists beyond startup window"],"tags":["orderer","etcdraft","raft","startup-race"],"backgroundTag":"chain-not-started","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"}