hyperledger/fabric · info
SyncBuffer stopping, channel: %s
Error message
SyncBuffer stopping, channel: %s
What it means
HandleBlock blocks trying to place a fetched block onto SyncBuffer's internal channel; if the buffer is shutting down (stopCh closed) the send is abandoned and this error reports that the SyncBuffer is stopping. It is a normal consequence of synchronization being cancelled (shutdown, reconfiguration, view change), not data corruption.
Source
Thrown at orderer/consensus/smartbft/sync_buffer.go:42
capacity = 10
}
return &SyncBuffer{
blockCh: make(chan *common.Block, capacity),
stopCh: make(chan struct{}),
}
}
// HandleBlock gives the block to the next stage of processing after fetching it from a remote orderer.
func (sb *SyncBuffer) HandleBlock(channelID string, block *common.Block) error {
if block == nil || block.Header == nil {
return errors.Errorf("empty block or block header, channel: %s", channelID)
}
select {
case sb.blockCh <- block:
return nil
case <-sb.stopCh:
return errors.Errorf("SyncBuffer stopping, channel: %s", channelID)
}
}
func (sb *SyncBuffer) PullBlock(seq uint64) *common.Block {
var block *common.Block
for {
select {
case block = <-sb.blockCh:
if block == nil || block.Header == nil {
return nil
}
if block.GetHeader().GetNumber() == seq {
return block
}
if block.GetHeader().GetNumber() < seq {
continue
}
if block.GetHeader().GetNumber() > seq {View on GitHub (pinned to 2736b63f8f)
Solutions
- No action needed if it appears during shutdown/restart — it is expected cancellation noise.
- If frequent, investigate why synchronization keeps being cancelled (chain restarts, flapping leader, channel churn) via orderer logs.
- Ensure graceful orderer shutdown ordering (stop services before killing the process) to minimize in-flight sync cancellations.
- Check for crash loops or channel join/remove automation racing with sync and serialize those operations.
Example fix
// before // killing orderer during sync kill -9 <orderer-pid> // after // graceful stop osnadmin channel join/remove settled first systemctl stop fabric-orderer
Defensive patterns
Strategy: try-catch
Try / catch
err := sb.HandleBlock(channelID, block)
if err != nil && strings.Contains(err.Error(), "SyncBuffer stopping") {
// expected during shutdown: log at debug and exit cleanly
logger.Debugf("sync aborted, buffer stopping: %v", err)
return nil
} Prevention
- Use graceful shutdown hooks so syncs finish or cancel cleanly.
- Avoid joining/removing channels while sync is actively in progress.
- Treat this error as cancellation, not corruption — do not retry aggressively on stop.
- Correlate with lifecycle events in logs before alerting.
When it happens
Trigger: A block arrives from the puller at the same moment the orderer/chain is shutting down or the sync loop is being stopped (e.g. channel halt, node restart, chain reconfiguration), closing stopCh while HandleBlock is mid-delivery.
Common situations: Orderer shutdown or restart while background synchronization is in flight; channel removal via the participation API during an active sync; a view/leader change cancelling an ongoing synchronization.
Related errors
- empty block or block header, channel: %s
- cannot get create BlockPuller
- consenter options type mismatch
- communication has been shut down
- failed to unmarshal BFT metadata configuration
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/4724c23af8e6e594.
Report an issue: GitHub.