{"record":{"id":"02332802879d01a6","repo":"hyperledger/fabric","slug":"block-deliverer-for-channel-s-is-nil-can-t-s","errorCode":null,"errorMessage":"block deliverer for channel `%s` is <nil>, can't stop delivery","messagePattern":"block deliverer for channel `(.+?)` is <nil>, can't stop delivery","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/deliverservice/deliveryclient.go","lineNumber":310,"sourceCode":"\n\treturn dcBFT, nil\n}\n\n// StopDeliverForChannel stops blocks delivery for channel by stopping channel block provider\nfunc (d *deliverServiceImpl) StopDeliverForChannel() error {\n\td.lock.Lock()\n\tdefer d.lock.Unlock()\n\n\tif d.stopping {\n\t\terrMsg := fmt.Sprintf(\"block deliverer for channel `%s` is already stopped\", d.channelID)\n\t\tlogger.Errorf(\"Delivery service: %s\", errMsg)\n\t\treturn errors.New(errMsg)\n\t}\n\n\tif d.blockDeliverer == nil {\n\t\terrMsg := fmt.Sprintf(\"block deliverer for channel `%s` is <nil>, can't stop delivery\", d.channelID)\n\t\tlogger.Errorf(\"Delivery service: %s\", errMsg)\n\t\treturn errors.New(errMsg)\n\t}\n\td.blockDeliverer.Stop()\n\td.blockDeliverer = nil\n\n\tlogger.Debugf(\"This peer will stop passing blocks from orderer service to other peers on channel: %s\", d.channelID)\n\treturn nil\n}\n\n// Stop all service and release resources\nfunc (d *deliverServiceImpl) Stop() {\n\td.lock.Lock()\n\tdefer d.lock.Unlock()\n\t// Marking flag to indicate the shutdown of the delivery service\n\td.stopping = true\n\n\tif d.blockDeliverer != nil {\n\t\td.blockDeliverer.Stop()\n\t\td.blockDeliverer = nil","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/deliverservice/deliveryclient.go#L292-L328","documentation":"StopDeliverForChannel returns this error when d.blockDeliverer is nil, meaning no active block deliverer exists for the channel to stop. This happens if delivery was never started for the channel or a previous stop already cleared the deliverer.","triggerScenarios":"Calling StopDeliverForChannel(channelID) when StartDeliverForChannel was never called for that channel, or after a prior StopDeliverForChannel already set d.blockDeliverer = nil, or if start failed earlier (e.g. error 830).","commonSituations":"Stopping a channel that failed to start due to a TLS/config error; calling stop on a typo'd or removed channel ID; shutdown paths running after an earlier stop cleared state.","solutions":["Ensure StartDeliverForChannel succeeded before calling StopDeliverForChannel for that channel","Treat the error as benign if stop is intended to be idempotent and skip it","Check logs for an earlier start failure (e.g. 'failed to access client TLS configuration') that left the deliverer nil","Fix the channel ID / lifecycle ordering so stop only runs on started channels"],"exampleFix":"// before\nservice.StopDeliverForChannel(channelID) // may fail if never started\n// after\nif err := service.StopDeliverForChannel(channelID); err != nil &&\n    strings.Contains(err.Error(), \"is <nil>\") {\n    logger.Debugf(\"channel %s was not started; nothing to stop\", channelID)\n}","handlingStrategy":"validation","validationCode":"if !startedChannels[channelID] {\n    return fmt.Errorf(\"channel %s was never started\", channelID)\n}","typeGuard":"func isNilDelivererErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"is <nil>\")\n}","tryCatchPattern":"if err := svc.StopDeliverForChannel(ch); err != nil {\n    if isNilDelivererErr(err) {\n        logger.Debugf(\"nothing to stop for %s\", ch)\n        return nil\n    }\n    return err\n}","preventionTips":["Only stop channels whose StartDeliverForChannel returned success","Handle start failures before entering stop/shutdown paths","Log channel lifecycle transitions to spot out-of-order start/stop"],"tags":["lifecycle","nil-receiver","hyperledger-fabric"],"backgroundTag":"nil-deliverer","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"}