hyperledger/fabric · error

policy manager for channel %s doesn't exist

Error message

policy manager for channel %s doesn't exist

What it means

ChannelVerifier.VerifyByChannel verifies a discovery request's signature against the channel's Application writers policy. Before fetching the policy it looks up the channel's policy manager; if none exists for the channel, verification aborts with this error — again meaning the peer doesn't know this channel.

Source

Thrown at discovery/support/acl/support.go:134

		Policy:                     policy,
		ChannelPolicyManagerGetter: polMgr,
	}
}

// ChannelVerifier verifies a signature and a message on the context of a channel
type ChannelVerifier struct {
	policies.ChannelPolicyManagerGetter
	Policy string
}

// VerifyByChannel checks that signature is a valid signature of message
// under a peer's verification key, but also in the context of a specific channel.
// If the verification succeeded, Verify returns nil meaning no error occurred.
// If peerIdentity is nil, then the verification fails.
func (cv *ChannelVerifier) VerifyByChannel(channel string, sd *protoutil.SignedData) error {
	mgr := cv.Manager(channel)
	if mgr == nil {
		return errors.Errorf("policy manager for channel %s doesn't exist", channel)
	}
	pol, _ := mgr.GetPolicy(cv.Policy)
	if pol == nil {
		return errors.New("failed obtaining channel application writers policy")
	}
	return pol.EvaluateSignedData([]*protoutil.SignedData{sd})
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Confirm the peer is joined to the channel (peer channel list) and that the name matches exactly
  2. Restart the peer and verify the channel's genesis block/ledger initialized cleanly
  3. Send the discovery request to a peer that is a member of the target channel
Defensive patterns

Strategy: validation

Validate before calling

if !slices.Contains(joinedChannels, channelID) {
    return fmt.Errorf("peer not joined to channel %s", channelID)
}

Type guard

func channelKnown(channels []string, ch string) bool {
    return slices.Contains(channels, ch)
}

Try / catch

res, err := client.Send(ctx, req)
if err != nil {
    if strings.Contains(err.Error(), "policy manager") && strings.Contains(err.Error(), "doesn't exist") {
        // target a different peer or correct the channel
    }
    return err
}

Prevention

When it happens

Trigger: A signed discovery request with AuthInfo.Channel naming a channel whose policy manager lookup (cv.Manager(channel)) returns nil — the peer has no policy manager registered for that channel.

Common situations: Discovery request sent to a peer not joined to the channel; channel name typo; ledger/policy manager not yet initialized because the peer hasn't finished starting or the channel genesis block is missing.

Related errors


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