{"record":{"id":"880bc0102d75c349","repo":"hyperledger/fabric","slug":"failed-capabilities-check-s","errorCode":null,"errorMessage":"Failed capabilities check: [%s]","messagePattern":"Failed capabilities check: \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/scc/cscc/configure.go","lineNumber":248,"sourceCode":"\t}\n\n\tif configEnv.Config.ChannelGroup == nil {\n\t\treturn errors.New(\"Nil channel group\")\n\t}\n\n\tif configEnv.Config.ChannelGroup.Groups == nil {\n\t\treturn errors.New(\"No channel configuration groups are available\")\n\t}\n\n\t_, exists := configEnv.Config.ChannelGroup.Groups[channelconfig.ApplicationGroupKey]\n\tif !exists {\n\t\treturn errors.Errorf(\"Invalid configuration block, missing %s \"+\n\t\t\t\"configuration group\", channelconfig.ApplicationGroupKey)\n\t}\n\n\t// Check the capabilities requirement\n\tif err = channelconfig.ValidateCapabilities(block, bccsp); err != nil {\n\t\treturn errors.Errorf(\"Failed capabilities check: [%s]\", err)\n\t}\n\n\treturn nil\n}\n\n// joinChain will join the specified chain in the configuration block.\n// Since it is the first block, it is the genesis block containing configuration\n// for this chain, so we want to update the Chain object with this info\nfunc (e *PeerConfiger) joinChain(\n\tchannelID string,\n\tblock *common.Block,\n\tdeployedCCInfoProvider ledger.DeployedChaincodeInfoProvider,\n\tlr plugindispatcher.LifecycleResources,\n\tnr plugindispatcher.CollectionAndLifecycleResources,\n) *pb.Response {\n\tif err := e.peer.CreateChannel(channelID, block, deployedCCInfoProvider, lr, nr); err != nil {\n\t\treturn shim.Error(err.Error())\n\t}","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/scc/cscc/configure.go#L230-L266","documentation":"This error is raised by validateConfigBlock in the system chaincode (core/scc/cscc/configure.go) when a configuration block fails Hyperledger Fabric capability validation. It wraps the underlying error returned by channelconfig.ValidateCapabilities, meaning the channel config block requires capabilities the peer does not support (or the config uses a missing application group). It blocks joinChain from proceeding with an incompatible channel configuration.","triggerScenarios":"Invoking cscc.InvokeNoShim (e.g. JoinChain via the CSCC system chaincode) with a genesis/config block whose channelconfig.ValidateCapabilities check fails — typically a config block that enables V2_0+ capabilities while the peer binary supports only older ones, or a block missing the Application group.","commonSituations":"Joining a channel created with newer channel/application capability levels by an older peer; mixed-version Fabric networks during upgrade; genesis blocks generated with configtxgen defaults newer than the peer's supported capabilities.","solutions":["Upgrade the peer binary to a version supporting the capabilities declared in the channel config","Regenerate the genesis block with capability levels matching the peer's supported versions (lower channel/application capabilities in configtx.yaml)","Verify the config block actually contains the channelconfig.ApplicationGroup; if missing, rebuild it with configtxgen","Check the peer log for the wrapped inner error from ValidateCapabilities to identify the exact unsupported capability"],"exampleFix":"# before (configtx.yaml, peer too old)\nCapabilities:\n  Channel: &ChannelCapabilities V2_0\n  Application: &ApplicationCapabilities V2_0\n# after\nCapabilities:\n  Channel: &ChannelCapabilities V1_4_3\n  Application: &ApplicationCapabilities V1_4_2","handlingStrategy":"validation","validationCode":"// before JoinChain\nenvelope, _ := utils.GetEnvelopeFromBlock(configBlock)\npayload, _ := utils.UnmarshalPayload(envelope.Payload)\nchdr, _ := channels.HeaderFrom(payload)\ncapabilityProvider, err := capabilities.GetProvider(chdr.ChannelId)\nif err != nil || capabilityProvider == nil { return fmt.Errorf(\"cannot obtain capability provider for channel\") }\n// ensure peer binary supports the config's declared capabilities by keeping peer and channel capability versions aligned\n","typeGuard":null,"tryCatchPattern":"// Go\nif err := validateConfigBlock(block, bccsp); err != nil {\n    var capErr *fmt.Errorf\n    if errors.As(err, &capErr) && strings.Contains(err.Error(), \"Failed capabilities check\") {\n        // do not join; surface capability version to operator\n        return fmt.Errorf(\"channel requires newer capabilities: %w\", err)\n    }\n    return err\n}","preventionTips":["Keep channel/application capability levels in configtx.yaml at or below the peer binary's supported versions","Upgrade all peers before raising channel capabilities in a rolling upgrade","Validate the genesis block with configtxgen/configtxlator before JoinChain","Log the wrapped inner capability error to pinpoint the unsupported capability"],"tags":["hyperledger-fabric","capabilities","channel-config","version-mismatch"],"backgroundTag":"capability-version-mismatch","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"}