{"record":{"id":"43da62038e7d2d6c","repo":"hyperledger/fabric","slug":"channel-s-not-found-43da62","errorCode":null,"errorMessage":"channel %s not found","messagePattern":"channel (.+?) not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/server/server.go","lineNumber":198,"sourceCode":"\t\t\tfunction: \"Broadcast\",\n\t\t},\n\t})\n}\n\n// Deliver sends a stream of blocks to a client after ordering\nfunc (s *server) Deliver(srv ab.AtomicBroadcast_DeliverServer) error {\n\tlogger.Debugf(\"Starting new Deliver handler\")\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tlogger.Criticalf(\"Deliver client triggered panic: %s\\n%s\", r, debug.Stack())\n\t\t}\n\t\tlogger.Debugf(\"Closing Deliver stream\")\n\t}()\n\n\tpolicyChecker := func(env *cb.Envelope, channelID string) error {\n\t\tchain := s.GetChain(channelID)\n\t\tif chain == nil {\n\t\t\treturn errors.Errorf(\"channel %s not found\", channelID)\n\t\t}\n\t\t// In maintenance mode, we typically require the signature of /Channel/Orderer/Readers.\n\t\t// This will block Deliver requests from peers (which normally satisfy /Channel/Readers).\n\t\tsf := msgprocessor.NewSigFilter(policies.ChannelReaders, policies.ChannelOrdererReaders, chain)\n\t\treturn sf.Apply(env)\n\t}\n\tdeliverServer := &deliver.Server{\n\t\tPolicyChecker: deliver.PolicyCheckerFunc(policyChecker),\n\t\tReceiver: &deliverMsgTracer{\n\t\t\tReceiver: srv,\n\t\t\tmsgTracer: msgTracer{\n\t\t\t\tdebug:    s.debug,\n\t\t\t\tfunction: \"Deliver\",\n\t\t\t},\n\t\t},\n\t\tResponseSender: &responseSender{\n\t\t\tAtomicBroadcast_DeliverServer: srv,\n\t\t},","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/server/server.go#L180-L216","documentation":"The Deliver service's policy checker resolves the chain (channel) from the registrar for each deliver request. If s.GetChain(channelID) returns nil — the orderer does not service that channel — the deliver stream is rejected with this error before any signature filtering happens.","triggerScenarios":"A peer or client opening a Deliver/DeliverFiltered stream specifying a channel the orderer hasn't joined, or using the wrong channel name in the seek info envelope.","commonSituations":"Peer attempting to pull blocks for a channel the ordering node isn't part of; channels created on other orderers in a multi-group cluster; stale channel name in peer config after re-provisioning orderers (participation mode where channels must be re-joined after restart).","solutions":["Run osnadmin channel list on the orderer and join it to the requested channel with its genesis block","Verify the channel ID the peer uses for deliver matches an existing channel exactly","In a cluster, ensure the channel was created on all intended ordering nodes (consenter set) and they re-joined after restarts"],"exampleFix":"// before: deliver to channel without checking membership\nchat, _ := server.Deliver(ctx)\nchat.Send(seekInfoEnvFor(\"mychannel\"))\n\n// after: verify orderer membership first\nchannels, _ := osnadmin.ListChannels(ordererURL)\nif !channels.Contains(\"mychannel\") {\n\tosnadmin.JoinChannel(ordererURL, \"mychannel\", genesisBlockPath)\n}","handlingStrategy":"validation","validationCode":"// client before opening deliver stream\nchannels, _ := osnadmin.ListChannels(ordererURL)\nif !contains(channels, channelID) {\n    return fmt.Errorf(\"refusing deliver: orderer not joined to %s\", channelID)\n}","typeGuard":"func channelExistsOnOrderer(channels []types.ChannelInfo, id string) bool {\n    for _, c := range channels {\n        if c.Name == id { return true }\n    }\n    return false\n}","tryCatchPattern":"resp, err := deliverClient.Send(env)\nif err != nil {\n    if strings.Contains(err.Error(), \"not found\") && strings.Contains(err.Error(), channelID) {\n        return joinOrdererToChannel(channelID, genesisBlockPath) // then redeliver\n    }\n    return err\n}","preventionTips":["Discover channel membership dynamically rather than hardcoding orderer endpoints per channel","After scaling/replacing orderers, re-run channel join for every channel the node should service","Alert on deliver 'channel not found' responses in peer logs"],"tags":["hyperledger-fabric","orderer","deliver","channel-not-found"],"backgroundTag":"channel-not-found","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"}