hyperledger/fabric · error
channel %s not found
Error message
channel %s not found
What it means
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.
Source
Thrown at orderer/common/server/server.go:198
function: "Broadcast",
},
})
}
// Deliver sends a stream of blocks to a client after ordering
func (s *server) Deliver(srv ab.AtomicBroadcast_DeliverServer) error {
logger.Debugf("Starting new Deliver handler")
defer func() {
if r := recover(); r != nil {
logger.Criticalf("Deliver client triggered panic: %s\n%s", r, debug.Stack())
}
logger.Debugf("Closing Deliver stream")
}()
policyChecker := func(env *cb.Envelope, channelID string) error {
chain := s.GetChain(channelID)
if chain == nil {
return errors.Errorf("channel %s not found", channelID)
}
// In maintenance mode, we typically require the signature of /Channel/Orderer/Readers.
// This will block Deliver requests from peers (which normally satisfy /Channel/Readers).
sf := msgprocessor.NewSigFilter(policies.ChannelReaders, policies.ChannelOrdererReaders, chain)
return sf.Apply(env)
}
deliverServer := &deliver.Server{
PolicyChecker: deliver.PolicyCheckerFunc(policyChecker),
Receiver: &deliverMsgTracer{
Receiver: srv,
msgTracer: msgTracer{
debug: s.debug,
function: "Deliver",
},
},
ResponseSender: &responseSender{
AtomicBroadcast_DeliverServer: srv,
},View on GitHub (pinned to 2736b63f8f)
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
Example fix
// before: deliver to channel without checking membership
chat, _ := server.Deliver(ctx)
chat.Send(seekInfoEnvFor("mychannel"))
// after: verify orderer membership first
channels, _ := osnadmin.ListChannels(ordererURL)
if !channels.Contains("mychannel") {
osnadmin.JoinChannel(ordererURL, "mychannel", genesisBlockPath)
} Defensive patterns
Strategy: validation
Validate before calling
// client before opening deliver stream
channels, _ := osnadmin.ListChannels(ordererURL)
if !contains(channels, channelID) {
return fmt.Errorf("refusing deliver: orderer not joined to %s", channelID)
} Type guard
func channelExistsOnOrderer(channels []types.ChannelInfo, id string) bool {
for _, c := range channels {
if c.Name == id { return true }
}
return false
} Try / catch
resp, err := deliverClient.Send(env)
if err != nil {
if strings.Contains(err.Error(), "not found") && strings.Contains(err.Error(), channelID) {
return joinOrdererToChannel(channelID, genesisBlockPath) // then redeliver
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- channel %s doesn't exist
- OrdererOrg config does not allow sub-groups
- Attempted to set the batch size preferred max bytes (%v) gre
- Attempted to set the batch timeout to a invalid value: %s
- Attempted to set the batch timeout to a non-positive value:
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/43da62038e7d2d6c.
Report an issue: GitHub.