hyperledger/fabric · error

key level endorsement is not enabled, channel application ca

Error message

key level endorsement is not enabled, channel application capability of V1_3 or later is required

What it means

checkMetadataCap requires the channel's application capabilities to include KeyLevelEndorsement (V1_3 or later application capability). This error is thrown when the app config exists but the channel is configured at an older application capability level, so GetStateMetadata/PutStateMetadata (key-level endorsement state APIs) are disallowed.

Source

Thrown at core/chaincode/handler.go:615

func (h *Handler) registerTxid(msg *pb.ChaincodeMessage) bool {
	// Check if this is the unique state request from this chaincode txid
	if h.ActiveTransactions.Add(msg.ChannelId, msg.Txid) {
		return true
	}

	// Log the issue and drop the request
	chaincodeLogger.Errorf("[%s] Another request pending for this CC: %s, Txid: %s, ChannelID: %s. Cannot process.", shorttxid(msg.Txid), h.chaincodeID, msg.Txid, msg.ChannelId)
	return false
}

func (h *Handler) checkMetadataCap(channelId string) error {
	ac, exists := h.AppConfig.GetApplicationConfig(channelId)
	if !exists {
		return errors.Errorf("application config does not exist for %s", channelId)
	}

	if !ac.Capabilities().KeyLevelEndorsement() {
		return errors.New("key level endorsement is not enabled, channel application capability of V1_3 or later is required")
	}
	return nil
}

func (h *Handler) checkPurgePrivateDataCap(channelId string) error {
	ac, exists := h.AppConfig.GetApplicationConfig(channelId)
	if !exists {
		return errors.Errorf("application config does not exist for %s", channelId)
	}

	if !ac.Capabilities().PurgePvtData() {
		return errors.New("purge private data is not enabled, channel application capability of V2_5 or later is required")
	}
	return nil
}

func errorIfCreatorHasNoReadPermission(chaincodeName, collection string, txContext *TransactionContext) error {
	rwPermission, err := getReadWritePermission(chaincodeName, collection, txContext)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Update the channel's Application capabilities to V1_3 or later (e.g. V2_0) via a channel config update transaction
  2. Ensure ordering of capability updates: orderer, then channel, then application capabilities
  3. Use configtxlator/configtxgen to edit and re-sign the updated channel config
  4. After update, restart/re-verify the peer sees the new capability before retrying the metadata call

Example fix

// before: configtx.yaml
# Capabilities:
#   Application: &ApplicationCapabilities
#     V1_2: true
// after
Capabilities:
  Application: &ApplicationCapabilities
    V2_0: true
Defensive patterns

Strategy: validation

Validate before calling

// check the channel's application capability before using metadata APIs:
// $ peer channel getinfo -c mychannel
// or fetch config and inspect: config.channel_group.groups.Application.values.Capabilities
if appCapability(mychannel) < "V1_3" {
    return fmt.Errorf("enable KeyLevelEndorsement: upgrade app capability to >= V1_3")
}

Prevention

When it happens

Trigger: Chaincode calls SetStateMetadata/GetStateMetadata on a channel whose Application capabilities section in configtx.yaml is set to V1_2 or lower; after upgrading Fabric binaries without updating the channel capability.

Common situations: Fabric network upgraded from v1.2/v1.3 to v2.x but channel application capabilities left at V1_2; developers testing key-level endorsement on legacy test channels; capability update ordering mistakes (capabilities must be enabled before using the APIs).

Related errors


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