hyperledger/fabric · error

unknown chaincode '%s' for channel '%s'

Error message

unknown chaincode '%s' for channel '%s'

What it means

ChaincodeInfo throws this when the channel exists in the cache but the requested chaincode name has no entry in that channel's cached Chaincodes map. The cache only contains chaincodes with committed definitions in the new lifecycle; anything not defined (or not yet approved/committed) is 'unknown'.

Source

Thrown at core/chaincode/lifecycle/cache.go:358

	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, err
	}

	return &LocalChaincodeInfo{

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Commit the chaincode definition on the channel ('peer lifecycle chaincode commit') before querying.
  2. Verify the exact chaincode name; names are case-sensitive.
  3. Wait for / trigger cache update on the block containing the definition commit, or restart peer if cache handling is suspected broken.
  4. Handle this as a not-found condition in caller logic.

Example fix

// before
info, err := cache.ChaincodeInfo("mychannel", "mycc")
// after
info, err := cache.ChaincodeInfo("mychannel", "mycc")
if err != nil && strings.Contains(err.Error(), "unknown chaincode") {
    return nil, fmt.Errorf("chaincode mycc not defined yet: approve and commit first")
}
Defensive patterns

Strategy: try-catch

Validate before calling

approved, err := lc.CheckChaincodeDefinitionApproved(channelID, name, orgMSPID) // ensure defined before info lookup
if err != nil || !approved { return nil, fmt.Errorf("%s not defined on %s", name, channelID) }

Try / catch

info, err := cache.ChaincodeInfo(channelID, name)
var notFound bool
if err != nil && strings.Contains(err.Error(), "unknown chaincode") { notFound = true }
if notFound { return nil, ErrChaincodeNotDefined }

Prevention

When it happens

Trigger: Calling ChaincodeInfo(channelID, name) where name was never defined via _lifecycle approveformyorg/commit, or the cache has not yet processed the committed definition update.

Common situations: Querying a chaincode before 'commit' completed; misspelled chaincode name; cache stale because the listener update for the new definition hasn't landed; checking on a peer that hasn't synced the defining block.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/2575e9f0d4be7d8f. Report an issue: GitHub.