hyperledger/fabric · error

channel %s doesn't exist

Error message

channel %s doesn't exist

What it means

The cluster ingress dispatcher routes incoming ConsensusRequest messages to the in-memory chain registered for the target channel via ChainSelector.ReceiverByChain. If no chain/follower exists locally for that channel name, this error is returned to the remote sender, indicating consensus traffic addressed to a channel this orderer has not joined (or has since left).

Source

Thrown at orderer/consensus/smartbft/ingress.go:48

	ReceiverByChain(channelID string) MessageReceiver
}

type WarningLogger interface {
	Warningf(template string, args ...any)
}

// Ingress dispatches Submit and Step requests to the designated per chain instances
type Ingress struct {
	Logger        WarningLogger
	ChainSelector ReceiverGetter
}

// OnConsensus notifies the Ingress for a reception of a StepRequest from a given sender on a given channel
func (in *Ingress) OnConsensus(channel string, sender uint64, request *ab.ConsensusRequest) error {
	receiver := in.ChainSelector.ReceiverByChain(channel)
	if receiver == nil {
		in.Logger.Warningf("An attempt to send a consensus request to a non existing channel (%s) was made by %d", channel, sender)
		return errors.Errorf("channel %s doesn't exist", channel)
	}
	msg := &protos.Message{}
	if err := proto.Unmarshal(request.Payload, msg); err != nil {
		in.Logger.Warningf("Malformed message: %v", err)
		return errors.Wrap(err, "malformed message")
	}
	receiver.HandleMessage(sender, msg)
	return nil
}

// OnSubmit notifies the Ingress for a reception of a SubmitRequest from a given sender on a given channel
func (in *Ingress) OnSubmit(channel string, sender uint64, request *ab.SubmitRequest) error {
	receiver := in.ChainSelector.ReceiverByChain(channel)
	if receiver == nil {
		in.Logger.Warningf("An attempt to submit a transaction to a non existing channel (%s) was made by %d", channel, sender)
		return errors.Errorf("channel %s doesn't exist", channel)
	}
	receiver.HandleRequest(sender, protoutil.MarshalOrPanic(request.Payload))

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Join the orderer to the channel with the latest config block (osnadmin channel join) so the receiver is registered
  2. Verify the channel ID in the request matches the joined channel name exactly (no typos)
  3. Check orderer logs for earlier chain-start failures (e.g. BFTChain creation errors) that left the channel unregistered, and fix the root cause
  4. Ensure all cluster members have consistent channel membership; remove the channel from nodes that shouldn't serve it
Defensive patterns

Strategy: try-catch

Validate before calling

// Sender-side: verify the target channel is joined locally before sending consensus traffic
if receiverByChain(channelID) == nil {
    return fmt.Errorf("not joined to channel %s; join before exchanging consensus messages", channelID)
}

Try / catch

err := ingress.OnConsensus(channel, sender, req)
if err != nil && strings.Contains(err.Error(), "doesn't exist") {
    log.Warnf("consensus msg for unknown channel %s from %d; dropping", channel, sender)
    // do not retry: join the channel first or stop routing traffic to this node
}

Prevention

When it happens

Trigger: A remote consenter sends an ab.ConsensusRequest on a channel for which this node has no active chain (never joined via osnadmin, chain failed to start, or the channel was removed) — OnConsensus finds receiver == nil.

Common situations: Cluster nodes with inconsistent channel membership (one node joined, others not); channel just removed locally while peers still route to it; typo/mismatch in channel ID during osnadmin operations; chain creation failed earlier so the receiver map is empty.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/8ed0272952d0d811. Report an issue: GitHub.