hyperledger/fabric · error
could not get application config for channel '%s'
Error message
could not get application config for channel '%s'
What it means
ChaincodeEndorsementInfo obtains the channel config successfully but channelConfig.ApplicationConfig() reports !ok, so the application capabilities cannot be checked (specifically LifecycleV20()) before routing to LegacyImpl or the new lifecycle. A well-formed application channel always has an Application config group, so this signals a malformed or non-application channel config.
Source
Thrown at core/chaincode/lifecycle/endorsement_info.go:124
// 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 {
chaincodeInfo.InstallInfo = &ChaincodeInstallInfo{}
}
return &ChaincodeEndorsementInfo{View on GitHub (pinned to 2736b63f8f)
Solutions
- Inspect the latest config block and verify the Application group and capabilities exist.
- Regenerate and apply a correct channel config from configtx.yaml (with Application capabilities set, e.g. V2_0).
- Perform a config update to restore the Application section if it was removed.
Defensive patterns
Strategy: validation
Validate before calling
// Go: ensure capabilities are checkable before lifecycle routing
cc := channelConfigSource.GetStableChannelConfig(channelID)
ac, ok := cc.ApplicationConfig()
if !ok || !ac.Capabilities().LifecycleV20() {
// expect legacy routing; anything else indicates a config problem
} Type guard
func hasLifecycleV20(cc ChannelConfig) bool {
ac, ok := cc.ApplicationConfig()
return ok && ac.Capabilities().LifecycleV20()
} Try / catch
if err != nil && strings.Contains(err.Error(), "could not get application config") {
// regenerate channel config with Application group + capabilities
} Prevention
- Set Application.Capabilities (e.g. V2_0) in configtx.yaml before channel creation.
- Validate generated config blocks contain the Application group before genesis.
- After any channel update, re-inspect ApplicationConfig availability.
When it happens
Trigger: ChaincodeEndorsementInfo executes GetStableChannelConfig then ApplicationConfig() during endorsement, and the channel config snapshot lacks the /Channel/Application group.
Common situations: Channel config block corrupted or hand-crafted without Application section; unusual/system-style channel used for chaincode invocation; config update stripped the Application group.
Related errors
- %s capability %s is required but not supported
- application config does not exist for %s
- key level endorsement is not enabled, channel application ca
- purge private data is not enabled, channel application capab
- could not get application config for channel '%s'
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b107ca7802819abf.
Report an issue: GitHub.