hyperledger/fabric · error
requested to Send for channel %s, but no such channel exists
Error message
requested to Send for channel %s, but no such channel exists
What it means
SendByCriteria resolves the target channel via chanState.getGossipChannelByChainID when criteria.Channel is set. If no gossip channel was joined for that chain ID, membership cannot be scoped, so the send is rejected with this error rather than broadcasting blindly.
Source
Thrown at gossip/gossip/gossip_impl.go:643
// SendByCriteria sends a given message to all peers that match the given SendCriteria
func (g *Node) SendByCriteria(msg *protoext.SignedGossipMessage, criteria SendCriteria) error {
if criteria.MaxPeers == 0 {
return nil
}
if criteria.Timeout == 0 {
return errors.New("Timeout should be specified")
}
if criteria.IsEligible == nil {
criteria.IsEligible = filter.SelectAllPolicy
}
membership := g.disc.GetMembership()
if len(criteria.Channel) > 0 {
gc := g.chanState.getGossipChannelByChainID(criteria.Channel)
if gc == nil {
return fmt.Errorf("requested to Send for channel %s, but no such channel exists", criteria.Channel)
}
membership = gc.GetPeers()
}
peers2send := filter.SelectPeers(criteria.MaxPeers, membership, criteria.IsEligible)
if len(peers2send) < criteria.MinAck {
return fmt.Errorf("requested to send to at least %d peers, but know only of %d suitable peers", criteria.MinAck, len(peers2send))
}
results := g.comm.SendWithAck(msg, criteria.Timeout, criteria.MinAck, peers2send...)
for _, res := range results {
if res.Error() == "" {
continue
}
g.logger.Warning("Failed sending to", res.Endpoint, "error:", res.Error())
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Call JoinChan (or ensure the peer actually joined) for the target channel before sending
- Verify the exact channel ID bytes match the channel's name (channel is a []byte compared by value)
- Check the peer's gossip membership/state to confirm the channel exists before issuing the send
Example fix
// before
g.SendByCriteria(msg, SendCriteria{Channel: []byte("my-channel"), Timeout: time.Second, MaxPeers: 2})
// after
if g.chanState.getGossipChannelByChainID([]byte("my-channel")) == nil {
g.JoinChan(joinMsg, common.ChainID("my-channel"))
}
g.SendByCriteria(msg, SendCriteria{Channel: []byte("my-channel"), Timeout: time.Second, MaxPeers: 2}) Defensive patterns
Strategy: validation
Validate before calling
// Confirm the channel exists before sending
if gc := g.chanState.getGossipChannelByChainID(criteria.Channel); gc == nil {
return fmt.Errorf("cannot send: not joined to channel %s", criteria.Channel)
}
err := g.SendByCriteria(msg, criteria) Try / catch
if err := g.SendByCriteria(msg, criteria); err != nil && strings.Contains(err.Error(), "no such channel exists") {
logger.Warningf("skipping send, not a member of %s", criteria.Channel)
return
} Prevention
- Call JoinChan before any channel-scoped gossip sends
- Compare channel IDs as exact byte slices; use common.ChainID to avoid typos
- Log membership state when a channel-scoped send fails
When it happens
Trigger: Calling SendByCriteria with criteria.Channel set to a channel name the node never joined (JoinChan not called), a misspelled chain ID, or a channel the node left/stopped before the send.
Common situations: Sending messages to peers on a newly created channel before the local node's gossip service joined it; byte-slice channel names compared by exact bytes so typos or wrong encoding slip through; channel removed by config change while a sender still targets it.
Related errors
- Channel %s doesn't exist
- Could not acquire policy manager for channel %s
- specified --channelID %s does not match channel ID %s in con
- specified --channelID %s does not match channel ID %s in con
- could not get msp for channel [%s]
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/f63826b906bc57aa.
Report an issue: GitHub.