hyperledger/fabric · error
unknown channel '%s'
Error message
unknown channel '%s'
What it means
ChaincodeInfo throws this when the cache has no entry for the requested channelID in definedChaincodes. The cache only learns channels via Initialize/SetChaincodesMapForUninitializedChannels, so a channel that was never initialized (or unknown channel ID) yields 'unknown channel'.
Source
Thrown at core/chaincode/lifecycle/cache.go:355
// ChaincodeInfo returns the chaincode definition and its install info.
// An error is returned only if either the channel or the chaincode do not exist.
func (c *Cache) ChaincodeInfo(channelID, name string) (*LocalChaincodeInfo, error) {
if name == LifecycleNamespace {
ac, ok := c.Resources.ChannelConfigSource.GetStableChannelConfig(channelID).ApplicationConfig()
if !ok {
return nil, errors.Errorf("application config does not exist for channel '%s'", channelID)
}
if !ac.Capabilities().LifecycleV20() {
return nil, errors.Errorf("cannot use _lifecycle without V2_0 application capabilities enabled for channel '%s'", channelID)
}
return c.getLifecycleSCCChaincodeInfo(channelID)
}
c.mutex.RLock()
defer c.mutex.RUnlock()
channelChaincodes, ok := c.definedChaincodes[channelID]
if !ok {
return nil, errors.Errorf("unknown channel '%s'", channelID)
}
cachedChaincode, ok := channelChaincodes.Chaincodes[name]
if !ok {
return nil, errors.Errorf("unknown chaincode '%s' for channel '%s'", name, channelID)
}
return &LocalChaincodeInfo{
Definition: cachedChaincode.Definition,
InstallInfo: cachedChaincode.InstallInfo,
Approved: cachedChaincode.Approved,
}, nil
}
func (c *Cache) getLifecycleSCCChaincodeInfo(channelID string) (*LocalChaincodeInfo, error) {
policyBytes, err := c.Resources.LifecycleEndorsementPolicyAsBytes(channelID)
if err != nil {
return nil, errView on GitHub (pinned to 2736b63f8f)
Solutions
- Verify the peer has joined the channel ('peer channel list') and the channelID spelling is exact.
- Ensure Cache.Initialize(channelID, queryExecutor) or SetChaincodesMapForUninitializedChannels ran before querying.
- Re-check that channel initialization completed (peer channel initialization, INITIALIZE channel ledger).
- If the channel is genuinely absent, treat this as an expected 'not found' and handle it, not as a retryable fault.
Example fix
// before
info, err := cache.ChaincodeInfo(channelID, name)
// after
if _, joined := joinedChannels[channelID]; !joined {
return nil, fmt.Errorf("skip: peer not joined to %s", channelID)
}
info, err := cache.ChaincodeInfo(channelID, name) Defensive patterns
Strategy: validation
Validate before calling
joined, _ := stub.GetChannels() // or peer channel list
if !containsChannel(joined, channelID) {
return fmt.Errorf("peer not joined to channel %s", channelID)
} Try / catch
info, err := cache.ChaincodeInfo(channelID, name)
if err != nil && strings.Contains(err.Error(), "unknown channel") {
return nil, fmt.Errorf("channel %s not initialized in cache: %w", channelID, err)
} Prevention
- Confirm channel membership with 'peer channel list' before lifecycle queries.
- Ensure cache Initialize/SetChaincodesMapForUninitializedChannels runs at peer startup for joined channels.
- Keep channel names in a single source of truth (config/env) to avoid typos.
When it happens
Trigger: Calling ChaincodeInfo with a channelID never initialized in the cache — e.g. peer has not joined the channel, or the cache was constructed but RegisterListener/InitializeMetadata was never run for that channel.
Common situations: Typo'd channel name; peer joined the channel after callers started querying; cache created before channel initialization completed; querying a channel the peer is not a member of.
Related errors
- too few arguments
- chaincode type not supported: %s
- incorrect number of arguments
- failed to copy metadataDir directory folder: %s
- connection.json not found in source folder: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/2dd4ffd4c25141de.
Report an issue: GitHub.