{"record":{"id":"4724c23af8e6e594","repo":"hyperledger/fabric","slug":"syncbuffer-stopping-channel-s","errorCode":null,"errorMessage":"SyncBuffer stopping, channel: %s","messagePattern":"SyncBuffer stopping, channel: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"info","filePath":"orderer/consensus/smartbft/sync_buffer.go","lineNumber":42,"sourceCode":"\t\tcapacity = 10\n\t}\n\treturn &SyncBuffer{\n\t\tblockCh: make(chan *common.Block, capacity),\n\t\tstopCh:  make(chan struct{}),\n\t}\n}\n\n// HandleBlock gives the block to the next stage of processing after fetching it from a remote orderer.\nfunc (sb *SyncBuffer) HandleBlock(channelID string, block *common.Block) error {\n\tif block == nil || block.Header == nil {\n\t\treturn errors.Errorf(\"empty block or block header, channel: %s\", channelID)\n\t}\n\n\tselect {\n\tcase sb.blockCh <- block:\n\t\treturn nil\n\tcase <-sb.stopCh:\n\t\treturn errors.Errorf(\"SyncBuffer stopping, channel: %s\", channelID)\n\t}\n}\n\nfunc (sb *SyncBuffer) PullBlock(seq uint64) *common.Block {\n\tvar block *common.Block\n\tfor {\n\t\tselect {\n\t\tcase block = <-sb.blockCh:\n\t\t\tif block == nil || block.Header == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tif block.GetHeader().GetNumber() == seq {\n\t\t\t\treturn block\n\t\t\t}\n\t\t\tif block.GetHeader().GetNumber() < seq {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif block.GetHeader().GetNumber() > seq {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/sync_buffer.go#L24-L60","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n// killing orderer during sync\nkill -9 <orderer-pid>\n\n// after\n// graceful stop\nosnadmin channel join/remove settled first\nsystemctl stop fabric-orderer","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := sb.HandleBlock(channelID, block)\nif err != nil && strings.Contains(err.Error(), \"SyncBuffer stopping\") {\n    // expected during shutdown: log at debug and exit cleanly\n    logger.Debugf(\"sync aborted, buffer stopping: %v\", err)\n    return nil\n}","preventionTips":["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."],"tags":["hyperledger-fabric","smartbft","sync","shutdown"],"backgroundTag":"operation-cancelled-during-shutdown","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"}