{"record":{"id":"0450b5cb2a926f91","repo":"hyperledger/fabric","slug":"application-config-does-not-exist-for-channel-s","errorCode":null,"errorMessage":"application config does not exist for channel '%s'","messagePattern":"application config does not exist for channel '(.+?)'","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/lifecycle/cache.go","lineNumber":343,"sourceCode":"\t// NOTE: It's extremely tempting to acquire the write lock in HandleStateUpdate\n\t// and release it here, however, this is asking for a deadlock.  In particular,\n\t// because the 'write lock' on the state is only held for a short period\n\t// between HandleStateUpdate and StateCommitDone, it's possible (in fact likely)\n\t// that a chaincode invocation will acquire a read-lock on the world state, then attempt\n\t// to get chaincode info from the cache, resulting in a deadlock.  So, we choose\n\t// potential inconsistency between the cache and the world state which the callers\n\t// must detect and cope with as necessary.  Note, the cache will always be _at least_\n\t// as current as the committed state.\n\tc.eventBroker.ApproveOrDefineCommitted(channelName)\n}\n\n// ChaincodeInfo returns the chaincode definition and its install info.\n// An error is returned only if either the channel or the chaincode do not exist.\nfunc (c *Cache) ChaincodeInfo(channelID, name string) (*LocalChaincodeInfo, error) {\n\tif name == LifecycleNamespace {\n\t\tac, ok := c.Resources.ChannelConfigSource.GetStableChannelConfig(channelID).ApplicationConfig()\n\t\tif !ok {\n\t\t\treturn nil, errors.Errorf(\"application config does not exist for channel '%s'\", channelID)\n\t\t}\n\t\tif !ac.Capabilities().LifecycleV20() {\n\t\t\treturn nil, errors.Errorf(\"cannot use _lifecycle without V2_0 application capabilities enabled for channel '%s'\", channelID)\n\t\t}\n\t\treturn c.getLifecycleSCCChaincodeInfo(channelID)\n\t}\n\n\tc.mutex.RLock()\n\tdefer c.mutex.RUnlock()\n\tchannelChaincodes, ok := c.definedChaincodes[channelID]\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"unknown channel '%s'\", channelID)\n\t}\n\n\tcachedChaincode, ok := channelChaincodes.Chaincodes[name]\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"unknown chaincode '%s' for channel '%s'\", name, channelID)\n\t}","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/lifecycle/cache.go#L325-L361","documentation":"Cache.ChaincodeInfo in core/chaincode/lifecycle/cache.go throws this when querying the _lifecycle system chaincode and the channel's stable channel config has no Application config. In Fabric, a channel config might lack an Application group (e.g. ordering-only config). The cache cannot resolve _lifecycle info without application-level settings (capabilities, orgs).","triggerScenarios":"Calling ChaincodeInfo(channelID, \"_lifecycle\") when ChannelConfigSource.GetStableChannelConfig(channelID).ApplicationConfig() returns ok=false, i.e. the channel config has no Application group.","commonSituations":"Channel config edited or created without an Application section; querying a channel served mostly by orderers; a config update removed application config; wrong channel ID resolving to a malformed config.","solutions":["Verify the channel's config contains an Application group (falsify via 'configtxlator' or inspect the channel config block).","Re-add the Application section via a config update transaction with proper org signatures.","Confirm the channelID is correct and the peer has joined the intended channel.","Check ApplicationConfigSource wiring on the peer so stable channel config exposes ApplicationConfig."],"exampleFix":"// before: query with possibly missing app config\ninfo, err := cache.ChaincodeInfo(\"mychannel\", \"_lifecycle\")\n// after: guard first\ncc, ok := configSource.GetStableChannelConfig(\"mychannel\").ApplicationConfig()\nif !ok { return nil, fmt.Errorf(\"channel %s has no application config; fix channel config before using _lifecycle\", \"mychannel\") }\ninfo, err := cache.ChaincodeInfo(\"mychannel\", \"_lifecycle\")","handlingStrategy":"validation","validationCode":"if _, ok := configSource.GetStableChannelConfig(channelID).ApplicationConfig(); !ok {\n    return fmt.Errorf(\"channel %s has no application config; cannot query _lifecycle\", channelID)\n}","typeGuard":null,"tryCatchPattern":"info, err := cache.ChaincodeInfo(channelID, \"_lifecycle\")\nif err != nil {\n    if strings.Contains(err.Error(), \"application config does not exist\") {\n        return nil, errAppConfigMissing // typed sentinel\n    }\n    return nil, err\n}","preventionTips":["Always create channels from configtx profiles that define an Application group.","Validate channel config with configtxlator before submitting updates.","Check peer channel membership before querying lifecycle."],"tags":["fabric","channel-config","lifecycle"],"backgroundTag":"missing-application-config","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}