hyperledger/fabric · error
could not get channel config for channel '%s'
Error message
could not get channel config for channel '%s'
What it means
ChaincodeEndorsementInfo calls cei.Resources.ChannelConfigSource.GetStableChannelConfig(channelID) to decide whether V2.0 lifecycle is enabled; when it returns nil this error is raised. It indicates the channel configuration snapshot could not be retrieved for the given channel, so legacy vs. new lifecycle routing cannot be determined.
Source
Thrown at core/chaincode/lifecycle/endorsement_info.go:120
return chaincodeInfo, true, nil
}
// ChaincodeEndorsementInfo returns the information necessary to handle a chaincode invocation request, as well as a function to
// enforce security checks on the chaincode (in case the definition is from the legacy lscc).
func (cei *ChaincodeEndorsementInfoSource) ChaincodeEndorsementInfo(channelID, chaincodeName string, qe ledger.SimpleQueryExecutor) (*ChaincodeEndorsementInfo, error) {
if cei.BuiltinSCCs.IsSysCC(chaincodeName) {
return &ChaincodeEndorsementInfo{
Version: scc.SysCCVersion,
EndorsementPlugin: "escc",
EnforceInit: false,
ChaincodeID: scc.ChaincodeID(chaincodeName),
}, nil
}
// return legacy cc endorsement info if V20 is not enabled
channelConfig := cei.Resources.ChannelConfigSource.GetStableChannelConfig(channelID)
if channelConfig == nil {
return nil, errors.Errorf("could not get channel config for channel '%s'", channelID)
}
ac, ok := channelConfig.ApplicationConfig()
if !ok {
return nil, errors.Errorf("could not get application config for channel '%s'", channelID)
}
if !ac.Capabilities().LifecycleV20() {
return cei.LegacyImpl.ChaincodeEndorsementInfo(channelID, chaincodeName, qe)
}
chaincodeInfo, ok, err := cei.CachedChaincodeInfo(channelID, chaincodeName, qe)
if err != nil {
return nil, err
}
if !ok {
return cei.LegacyImpl.ChaincodeEndorsementInfo(channelID, chaincodeName, qe)
}
if chaincodeInfo.InstallInfo == nil {View on GitHub (pinned to 2736b63f8f)
Solutions
- Confirm the channelID is correct and the peer has joined it (`peer channel list`).
- Ensure the channel's config is available to the peer (channel created and ledger opened).
- If triggered by a race during channel teardown/update, retry after the channel state stabilizes.
Defensive patterns
Strategy: validation
Validate before calling
// Go: pre-flight channel existence before endorsement-sensitive calls
if vc.Resources.ChannelConfigSource.GetStableChannelConfig(channelID) == nil {
return fmt.Errorf("channel %s unknown to peer", channelID)
} Type guard
func channelKnown(src ChannelConfigSource, ch string) bool { return src.GetStableChannelConfig(ch) != nil } Try / catch
if err != nil && strings.Contains(err.Error(), "could not get channel config") {
// verify channelID and peer channel membership, retry if racing teardown
} Prevention
- Match the channelID in the signed proposal to a joined channel.
- Reject proposals for unknown channels at gateway/service layer.
- Add health checks that each expected channel config resolves.
- Avoid invoking during peer shutdown or channel deletion.
When it happens
Trigger: Endorsement path resolves ChaincodeEndorsementInfo for a chaincode whose cached info isn't available, and the channelID given has no entry in the channel config source (channel not joined/loaded, wrong channel name, or channel resources being destroyed).
Common situations: Invoking on a misspelled or nonexistent channel; peer asked to endorse for a channel it is not joined to; race during channel removal or peer shutdown.
Related errors
- could not get channel config for channel '%s'
- could not get application config for channel '%s'
- chaincode definition for '%s' exists, but chaincode is not i
- no application config for channel '%s'
- peer '%s' is defined in the channel config but doesn't have
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/d8a80ec9b334dd0f.
Report an issue: GitHub.