hyperledger/fabric · error
node %d doesn't exist in channel %s's membership
Error message
node %d doesn't exist in channel %s's membership
What it means
Thrown by the orderer cluster Comm layer's Remote() when the channel exists in Chan2Members but no node with the given ID is present in that channel's membership mapping (mapping.ByID(id) returned nil). The channel is known locally, but the specific cluster node is not a member of it, so no remote stub can be produced.
Source
Thrown at orderer/common/cluster/comm.go:132
}
// Remote obtains a RemoteContext linked to the destination node on the context
// of a given channel
func (c *Comm) Remote(channel string, id uint64) (*RemoteContext, error) {
c.Lock.RLock()
defer c.Lock.RUnlock()
if c.shutdown {
return nil, errors.New("communication has been shut down")
}
mapping, exists := c.Chan2Members[channel]
if !exists {
return nil, errors.Errorf("channel %s doesn't exist", channel)
}
stub := mapping.ByID(id)
if stub == nil {
return nil, errors.Errorf("node %d doesn't exist in channel %s's membership", id, channel)
}
if stub.Active() {
return stub.RemoteContext, nil
}
err := stub.Activate(c.createRemoteContext(stub, channel))
if err != nil {
return nil, errors.WithStack(err)
}
return stub.RemoteContext, nil
}
// Configure configures the channel with the given RemoteNodes
func (c *Comm) Configure(channel string, newNodes []RemoteNode) {
c.Logger.Infof("Entering, channel: %s, nodes: %v", channel, newNodes)
defer c.Logger.Infof("Exiting")
View on GitHub (pinned to 2736b63f8f)
Solutions
- Confirm the node ID exists in the channel's membership (check the channel's consenters/orderer endpoints configuration).
- Refresh membership via Configure/JoinChannel so Chan2Members reflects the current channel membership.
- Fix the caller to derive node IDs from the channel's own member list, not a global or cross-channel list.
- If membership changed recently, restart or reconfigure the orderer so it picks up the updated channel config.
Example fix
// before
remote, err := comm.Remote(channel, nodeIDFromOtherChannel)
// after
if mapping.Contains(nodeID) { // verify ID is in this channel's membership
remote, err = comm.Remote(channel, nodeID)
} Defensive patterns
Strategy: validation
Validate before calling
// Go: check the node ID is part of the channel's membership before Remote
members, ok := comm.Chan2Members[channel]
if !ok || members.ByID(id) == nil {
return fmt.Errorf("node %d is not a member of channel %q", id, channel)
} Type guard
func nodeInChannel(c *cluster.Comm, channel string, id uint64) bool {
c.RLock()
defer c.RUnlock()
mapping, ok := c.Chan2Members[channel]
if !ok {
return false
}
return mapping.ByID(id) != nil
} Try / catch
remote, err := comm.Remote(channel, id)
if err != nil {
if strings.Contains(err.Error(), "doesn't exist in channel") {
// refresh membership then retry, or fall back to another node
return comm.refreshMembershipAndRetry(channel, id)
}
return err
} Prevention
- Derive node IDs from the channel's own member list, never from global or cross-channel lists.
- Keep membership views fresh by re-running Configure after consenters change.
- Log the channel and ID on failure so stale-membership bugs surface quickly.
- After adding/removing orderers, verify each node's channel config includes the new consenters.
When it happens
Trigger: Calling Comm.Remote(channel, id) with a node ID that is not in the channel's configured member list, e.g. an ID from a different channel's membership, or an outdated membership view after config changes.
Common situations: Passing the wrong node ID (off-by-one or from another channel); membership cache is stale after adding/removing orderers; a caller iterates node IDs from a global list instead of the channel's own member list.
Related errors
- invalid request object
- session binding read failed
- communication has been shut down
- cannot enable channel capabilities without orderer support f
- Must set some OrdererAddresses
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/186cab8390bb95cf.
Report an issue: GitHub.