hyperledger/fabric · error
channel %s doesn't exist
Error message
channel %s doesn't exist
What it means
SupportImpl.NewQueryCreator could not obtain a ledger for the channel string passed in, meaning the peer has no such channel open. The peer's Peer.GetLedger returns nil for unknown or not-yet-opened channels, so the query creator (used as an endorsement plugin dependency) cannot be built.
Source
Thrown at core/endorser/support.go:49
GetApplicationConfig(cid string) (channelconfig.Application, bool)
GetLedger(cid string) ledger.PeerLedger
}
// SupportImpl provides an implementation of the endorser.Support interface
// issuing calls to various static methods of the peer
type SupportImpl struct {
*PluginEndorser
identity.SignerSerializer
Peer PeerOperations
ChaincodeSupport *chaincode.ChaincodeSupport
ACLProvider aclmgmt.ACLProvider
BuiltinSCCs scc.BuiltinSCCs
}
func (s *SupportImpl) NewQueryCreator(channel string) (QueryCreator, error) {
lgr := s.Peer.GetLedger(channel)
if lgr == nil {
return nil, errors.Errorf("channel %s doesn't exist", channel)
}
return lgr, nil
}
func (s *SupportImpl) SigningIdentityForRequest(*pb.SignedProposal) (endorsement.SigningIdentity, error) {
return s.SignerSerializer, nil
}
// GetTxSimulator returns the transaction simulator for the specified ledger
// a client may obtain more than one such simulator; they are made unique
// by way of the supplied txid
func (s *SupportImpl) GetTxSimulator(ledgername string, txid string) (ledger.TxSimulator, error) {
lgr := s.Peer.GetLedger(ledgername)
if lgr == nil {
return nil, errors.Errorf("Channel does not exist: %s", ledgername)
}
return lgr.NewTxSimulator(txid)
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Join the peer to the channel: peer channel fetch + peer channel join
- Confirm with 'peer channel list' that the peer is joined to the intended channel and fix the channel ID in the client config
- Wait for peer startup to complete and ledgers to open before submitting proposals
- Check peer logs for channel/ledger open failures
Example fix
// before: targeting peer not on channel
const proposal = channel.newProposal(fn, args);
// after: ensure peer membership
const peers = channel.getChannelPeers();
if (peers.length === 0) throw new Error('peer not joined to channel ' + channel.getName()); Defensive patterns
Strategy: validation
Validate before calling
const discovered = await discoveryService.getChannelPeers(channelName); const targets = peersOnChannel(discovered); // only endorse on peers that report the channel
Type guard
function peerHasChannel(peer, channelId) { return peer.channels?.includes(channelId) ?? false; } Try / catch
try {
return await endorseOnChannel(channelName);
} catch (e) {
if (e.message.includes("doesn't exist")) {
throw new Error(`peer is not joined to ${channelName}; join peer or fix channel ID`, { cause: e });
}
throw e;
} Prevention
- Verify 'peer channel list' includes the target channel before routing requests
- Use service discovery instead of hardcoding peers in connection profiles
- Wait for peer readiness before sending proposals after startup
- Keep a single source of truth for channel names in application config
When it happens
Trigger: initPlugin -> pe.NewQueryCreator(channel) -> SupportImpl.NewQueryCreator with a channel ID for which s.Peer.GetLedger(channel) returns nil — peer not joined to that channel, channel still opening, or channel name mistyped.
Common situations: Sending endorsement requests to a peer that never joined the channel; SDK connection profile listing the wrong channel ID; requests during peer startup before channel ledgers open; channel deleted or peer config changed.
Related errors
- failed obtaining channel state
- Channel does not exist: %s
- transient store for channel %s was not initialized
- failed to look up the ledger for Channel %s
- Could not retrieve ledger for channel %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/6d057bc1e09ee3eb.
Report an issue: GitHub.