hyperledger/fabric · warning
chain is not started
Error message
chain is not started
What it means
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.
Source
Thrown at orderer/consensus/etcdraft/chain.go:492
c.statusReportMutex.Lock()
defer c.statusReportMutex.Unlock()
// If the haltCallback registers the chain in to the inactive chain registry (i.e., system channel exists) then
// this is the correct consensusRelation. If the haltCallback transfers responsibility to a follower.Chain, then
// this chain is about to be GC anyway. The new follower.Chain replacing this one will report the correct
// StatusReport.
c.consensusRelation = types.ConsensusRelationConfigTracker
}
// active nodes metric shouldn't be frozen once a channel is stopped.
c.Metrics.ActiveNodes.Set(float64(0))
}
func (c *Chain) isRunning() error {
select {
case <-c.startC:
default:
return errors.Errorf("chain is not started")
}
select {
case <-c.doneC:
return errors.Errorf("chain is stopped")
default:
}
return nil
}
// Consensus passes the given ConsensusRequest message to the raft.Node instance
func (c *Chain) Consensus(req *orderer.ConsensusRequest, sender uint64) error {
if err := c.isRunning(); err != nil {
return err
}
stepMsg := &raftpb.Message{}View on GitHub (pinned to 2736b63f8f)
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.
Defensive patterns
Strategy: retry
Try / catch
if err := chain.WaitReady(); err != nil {
if strings.Contains(err.Error(), "chain is not started") {
time.Sleep(100 * time.Millisecond)
return chain.WaitReady() // transient startup race
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- unable to retrieve block [%d]
- failed to restore persisted raft data: %s
- failed to get last block
- chain is stopped
- failed to process Raft Step message: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/55cbb49407b5385c.
Report an issue: GitHub.