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 manager

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify the channel name matches exactly the channel the peer joined (peer channel list)
  2. Join the peer to the channel or route the discovery request to a peer that is joined
  3. 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

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


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