{"record":{"id":"38f777ec7a0800f7","repo":"hyperledger/fabric","slug":"no-policies-in-config-block-38f777","errorCode":null,"errorMessage":"no policies in config block","messagePattern":"no policies in config block","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/multichannel/registrar.go","lineNumber":401,"sourceCode":"\n\tbundle, err := channelconfig.NewBundle(chdr.ChannelId, configEnvelope.Config, r.bccsp)\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, \"error creating channelconfig bundle\")\n\t}\n\n\terr = checkResources(bundle)\n\tif err != nil {\n\t\treturn nil, errors.WithMessagef(err, \"error checking bundle for channel: %s\", chdr.ChannelId)\n\t}\n\n\tledger, err := r.ledgerFactory.GetOrCreate(chdr.ChannelId)\n\tif err != nil {\n\t\treturn nil, errors.WithMessagef(err, \"error getting ledger for channel: %s\", chdr.ChannelId)\n\t}\n\n\tpolicy, exists := bundle.PolicyManager().GetPolicy(policies.BlockValidation)\n\tif !exists {\n\t\treturn nil, errors.New(\"no policies in config block\")\n\t}\n\n\tbftEnabled := bundle.ChannelConfig().Capabilities().ConsensusTypeBFT()\n\n\tvar consenters []*cb.Consenter\n\tif bftEnabled {\n\t\tcfg, ok := bundle.OrdererConfig()\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"no orderer section in config block\")\n\t\t}\n\t\tconsenters = cfg.Consenters()\n\t}\n\tsignatureVerifier := protoutil.BlockSignatureVerifier(bftEnabled, consenters, policy)\n\n\treturn &ledgerResources{\n\t\tconfigResources: &configResources{\n\t\t\tmutableResources: channelconfig.NewBundleSource(bundle, r.callbacks...),\n\t\t\tbccsp:            r.bccsp,","sourceCodeStart":383,"sourceCodeEnd":419,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/multichannel/registrar.go#L383-L419","documentation":"After loading the channel bundle, the registrar looks up the BlockValidation policy (/Channel/Orderer/BlockValidation) in the channel's policy manager. A valid config block must define this policy because it is used to verify block signatures; if it is absent the channel cannot be validated and the ledger resources are not created.","triggerScenarios":"A channel config block (genesis or join block) whose Orderer group lacks the BlockValidation policy, e.g. a configtx.yaml profile that omits Policies for the Orderer group, or a channel created from a custom/legacy config template.","commonSituations":"Custom genesis profiles missing the default Orderer policies (Readers/Writers/Admins/BlockValidation), config generated by old tooling then imported into newer Fabric, or hand-edited channel config stripped of policy entries.","solutions":["Add the Orderer-group policies (including BlockValidation) to the configtx.yaml profile and regenerate the genesis/join block","Use the stock sample config (first-network / test-network profiles) as a template for the Orderer group policies","Re-create the channel from a correct config block; an existing bad block cannot be patched in place"],"exampleFix":"# before: configtx.yaml Orderer group without policies\nOrderer:\n  OrdererType: etcdraft\n\n# after\nOrderer:\n  OrdererType: etcdraft\n  Policies:\n    Readers:\n      Type: ImplicitMeta\n      Rule: \"ANY Readers\"\n    Writers:\n      Type: ImplicitMeta\n      Rule: \"ANY Writers\"\n    Admins:\n      Type: ImplicitMeta\n      Rule: \"MAJORITY Admins\"\n    BlockValidation:\n      Type: ImplicitMeta\n      Rule: \"ANY Writers\"","handlingStrategy":"validation","validationCode":"# validate channel config before use with configtxlator\ncurl -s -X POST --data-binary @config_block.proto \\\n  http://configtxlator:7059/protolator/decode/common.ConfigBlock\n# ensure Orderer group contains Policies.BlockValidation","typeGuard":"func hasBlockValidationPolicy(bundle channelconfig.Resources) bool {\n    _, ok := bundle.PolicyManager().GetPolicy(policies.BlockValidation)\n    return ok\n}","tryCatchPattern":"if err := joinChannel(...); err != nil {\n    if strings.Contains(err.Error(), \"no policies in config block\") {\n        // regenerate genesis block from a profile with full Orderer policies\n        return regenerateGenesisBlock(profile)\n    }\n    return err\n}","preventionTips":["Base custom profiles on the stock sample configtx.yaml which includes Readers/Writers/Admins/BlockValidation","Decode the genesis block with configtxlator and diff policies against a known-good block","Never hand-edit channel config JSON without re-validating policy groups"],"tags":["hyperledger-fabric","orderer","channel-config","policies"],"backgroundTag":"missing-channel-policy","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"}