{"record":{"id":"a4e8bc12c2f08dc3","repo":"hyperledger/fabric","slug":"channel-s-doesn-t-exist-a4e8bc","errorCode":null,"errorMessage":"Channel %s doesn't exist","messagePattern":"Channel (.+?) doesn't exist","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gossip/gossip/gossip_impl.go","lineNumber":762,"sourceCode":"func (g *Node) SelfMembershipInfo() discovery.NetworkMember {\n\treturn g.disc.Self()\n}\n\n// SelfChannelInfo returns the peer's latest StateInfo message of a given channel\nfunc (g *Node) SelfChannelInfo(chain common.ChannelID) *protoext.SignedGossipMessage {\n\tch := g.chanState.getGossipChannelByChainID(chain)\n\tif ch == nil {\n\t\treturn nil\n\t}\n\treturn ch.Self()\n}\n\n// PeerFilter receives a SubChannelSelectionCriteria and returns a RoutingFilter that selects\n// only peer identities that match the given criteria, and that they published their channel participation\nfunc (g *Node) PeerFilter(channel common.ChannelID, messagePredicate api.SubChannelSelectionCriteria) (filter.RoutingFilter, error) {\n\tgc := g.chanState.getGossipChannelByChainID(channel)\n\tif gc == nil {\n\t\treturn nil, errors.Errorf(\"Channel %s doesn't exist\", channel)\n\t}\n\treturn gc.PeerFilter(messagePredicate), nil\n}\n\n// Stop stops the gossip component\nfunc (g *Node) Stop() {\n\tif g.toDie() {\n\t\treturn\n\t}\n\tatomic.StoreInt32(&g.stopFlag, int32(1))\n\tg.logger.Info(\"Stopping gossip\")\n\tclose(g.toDieChan)\n\tg.stopSignal.Wait()\n\tg.chanState.stop()\n\tg.discAdapter.close()\n\tg.disc.Stop()\n\tg.certStore.stop()\n\tg.emitter.Stop()","sourceCodeStart":744,"sourceCodeEnd":780,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/gossip/gossip/gossip_impl.go#L744-L780","documentation":"Node.PeerFilter looks up the gossip channel for the given chain ID and returns this error wrapped via errors.Errorf when the channel is unknown. Routing filters need channel-scoped membership, so a missing channel means no valid filter can be produced.","triggerScenarios":"Calling PeerFilter (via computeFilters or getMatchAllRoutingFilter paths) with a common.ChannelID the local gossip node hasn't joined, or after the channel was removed from chanState.","commonSituations":"Pull/state message routing on channels that were stopped or never joined; channel ID typos; race where a channel is removed while message handlers still reference it.","solutions":["Ensure the node joined the channel (JoinChan) before obtaining routing filters for it","Verify the ChannelID bytes exactly match the channel name","Handle the error by skipping/requeueing the message rather than treating it as fatal"],"exampleFix":"// before\nfilter, err := g.PeerFilter(channel, predicate)\nfilter(...)\n\n// after\nfilter, err := g.PeerFilter(channel, predicate)\nif err != nil {\n    // channel doesn't exist; skip routing for this channel\n    return\n}\nfilter(...)","handlingStrategy":"try-catch","validationCode":"// check channel presence first\nif g.chanState.getGossipChannelByChainID(channel) == nil {\n    return nil, fmt.Errorf(\"channel %s not joined\", channel)\n}\nf, err := g.PeerFilter(channel, predicate)","typeGuard":null,"tryCatchPattern":"f, err := g.PeerFilter(channel, predicate)\nif err != nil {\n    logger.Debugf(\"no filter for channel %s: %v\", channel, err)\n    return nil // skip routing\n}","preventionTips":["Join the channel before building routing filters for it","Treat unknown-channel errors as skip signals in message handlers","Keep channel lifecycle (join/stop) synchronized with message routing code"],"tags":["gossip","hyperledger-fabric","channel"],"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"}