hyperledger/fabric · error
channel %s doesn't exist
Error message
channel %s doesn't exist
What it means
The discovery service's ACL check (SatisfiesPrincipal) resolves the channel's config via GetChannelConfig before evaluating a principal. If no channel config exists for the requested channel name, the channel does not exist on this peer and the authorization cannot proceed. This is the peer telling the client it asked about a channel that isn't joined.
Source
Thrown at discovery/support/acl/support.go:91
// No sequence if the channel is empty
if channel == "" {
return 0
}
conf := s.GetChannelConfig(channel)
if conf == nil {
logger.Panic("Failed obtaining channel config for channel", channel)
}
v := conf.ConfigtxValidator()
if v == nil {
logger.Panic("ConfigtxValidator for channel", channel, "is nil")
}
return v.Sequence()
}
func (s *DiscoverySupport) SatisfiesPrincipal(channel string, rawIdentity []byte, principal *msp.MSPPrincipal) error {
conf := s.GetChannelConfig(channel)
if conf == nil {
return errors.Errorf("channel %s doesn't exist", channel)
}
mspMgr := conf.MSPManager()
if mspMgr == nil {
return errors.Errorf("could not find MSP manager for channel %s", channel)
}
identity, err := mspMgr.DeserializeIdentity(rawIdentity)
if err != nil {
logger.Warnw("failed deserializing identity", "error", err, "identity", protoutil.LogMessageForSerializedIdentity(rawIdentity))
return errors.Wrap(err, "failed deserializing identity")
}
return identity.SatisfiesPrincipal(principal)
}
// ChannelPolicyManagerGetter is a support interface
// to get access to the policy manager of a given channel
type ChannelPolicyManagerGetter interface {
// Returns the policy manager associated to the passed channel
// and true if it was the manager requested, or false if it is the default managerView on GitHub (pinned to 2736b63f8f)
Solutions
- Verify the channel name matches exactly the channel the peer joined (peer channel list)
- Join the peer to the channel or route the discovery request to a peer that is joined
- Fix typos/case in the channel name in your connection profile or client code
Example fix
// before req.AddLocalPeersQuery() // AuthInfo.Channel: "mychanel" (typo) // after req.AddLocalPeersQuery() // AuthInfo.Channel: "mychannel" — verify with `peer channel list`
Defensive patterns
Strategy: validation
Validate before calling
// before issuing discovery:
out, err := exec.Command("peer", "channel", "list").Output()
if !strings.Contains(string(out), channelID) {
return fmt.Errorf("peer not joined to channel %s", channelID)
} Type guard
func peerKnowsChannel(joinedChannels []string, ch string) bool {
for _, c := range joinedChannels {
if c == ch { return true }
}
return false
} Try / catch
res, err := client.Send(ctx, req)
if err != nil {
if strings.Contains(err.Error(), "doesn't exist") {
// fall back to another peer or fix channel name
}
return err
} Prevention
- Copy channel names from `peer channel list` output, not memory
- Keep the connection profile in sync with actual peer channel membership
- Verify case-sensitive exact channel IDs
When it happens
Trigger: Sending a discovery request (endorsement, config, membership, or peers query) whose AuthInfo.Channel targets a channel the peer has not joined, or a misspelled/nonexistent channel name.
Common situations: Typos in the channel name in the SDK/client config; client assuming the peer joined all channels; channel was deleted or the peer was removed from it; stale connection profile after channel reconfiguration.
Related errors
- access denied
- could not find MSP manager for channel %s
- policy manager for channel %s doesn't exist
- failed obtaining channel application writers policy
- could not get last config for channel %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/0048aeb6c81236a6.
Report an issue: GitHub.