{"record":{"id":"c596acd314611710","repo":"hyperledger/fabric","slug":"no-orderer-config-in-config-block","errorCode":null,"errorMessage":"no orderer config in config block","messagePattern":"no orderer config in config block","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/util.go","lineNumber":299,"sourceCode":"// remoteNodesFromConfigBlock unmarshalls the node config from the block metadata\nfunc remoteNodesFromConfigBlock(block *cb.Block, logger *flogging.FabricLogger, bccsp bccsp.BCCSP) (*nodeConfig, error) {\n\tenv := &cb.Envelope{}\n\tif err := proto.Unmarshal(block.Data.Data[0], env); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed unmarshalling envelope of config block\")\n\t}\n\tbundle, err := channelconfig.NewBundleFromEnvelope(env, bccsp)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed getting a new bundle from envelope of config block\")\n\t}\n\n\tchannelMSPs, err := bundle.MSPManager().GetMSPs()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed obtaining MSPs from MSPManager\")\n\t}\n\n\toc, ok := bundle.OrdererConfig()\n\tif !ok {\n\t\treturn nil, errors.New(\"no orderer config in config block\")\n\t}\n\n\t_, err = createSmartBftConfig(oc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar nodeIDs []uint64\n\tvar remoteNodes []cluster.RemoteNode\n\tid2Identies := map[uint64][]byte{}\n\tfor _, consenter := range oc.Consenters() {\n\t\tsanitizedID, err := crypto.SanitizeIdentity(protoutil.MarshalOrPanic(&msp.SerializedIdentity{\n\t\t\tIdBytes: consenter.Identity,\n\t\t\tMspid:   consenter.MspId,\n\t\t}))\n\t\tif err != nil {\n\t\t\tlogger.Panicf(\"Failed to sanitize identity: %v [%s]\", err, string(consenter.Identity))\n\t\t}","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/util.go#L281-L317","documentation":"remoteNodesFromConfigBlock requires the config bundle to contain an Orderer group. bundle.OrdererConfig() returns ok=false when the channel configuration has no 'Orderer' ConfigGroup, so the SmartBFT consenter set cannot be derived. This error surfaces when a block handed to the smartBFT chain is a valid channel config but simply is not an orderer-channel config.","triggerScenarios":"configBlockCommitted -> remoteNodesFromConfigBlock on a config block whose Channel/ConfigGroup lacks the Orderer group (application-only channel config, or a block that is not the channel's genesis/config block).","commonSituations":"Pointing an orderer at a genesis/config block generated for an application channel without consenter settings; missing Orderer section in configtx.yaml profile; committing a channel config update that removed the Orderer group (virtually never intended); running SmartBFT on a channel whose consensus-type/orderer config was never set up.","solutions":["Verify the block passed to configBlockCommitted is the correct channel's config block (correct channelID, genesis block generated for an orderer profile)","Add an Orderer section to your configtx.yaml profile (Orderer: OrdererType, EtcdRaft/SmartBFT Consenters, Addresses) and regenerate the genesis block","Ensure the channel was created from a profile that includes orderer organizations and consenters","If this happened after a config update, inspect the update with configtxlator to confirm the Orderer group wasn't dropped"],"exampleFix":"// before: configtx.yaml profile without orderer section\nProfiles:\n  AppChannel:\n    Application:\n      Organizations: [...]\n\n// after\nProfiles:\n  AppChannel:\n    Orderer:\n      OrdererType: etcdraft  # / smartbft\n      Organizations:\n        - *OrdererOrg\n    Application:\n      Organizations: [...]","handlingStrategy":"validation","validationCode":"bundle, err := channelconfig.NewBundleFromEnvelope(env, bccsp)\nif err != nil {\n    return err\n}\nif _, ok := bundle.OrdererConfig(); !ok {\n    chID, _ := bundle.ConfigtxValidator().ChannelID(), nil\n    return fmt.Errorf(\"channel %s config has no Orderer group; use an orderer-capable configtx profile\", chID)\n}","typeGuard":"func hasOrdererConfig(bundle *channelconfig.Bundle) bool {\n    if bundle == nil {\n        return false\n    }\n    _, ok := bundle.OrdererConfig()\n    return ok\n}","tryCatchPattern":"oc, ok := bundle.OrdererConfig()\nif !ok {\n    return fmt.Errorf(\"channel %q is not an orderer channel; regenerate genesis block from a profile with an Orderer section\", bundle.ConfigtxValidator().ChannelID())\n}","preventionTips":["Always include an Orderer section (OrdererType, Consenters, Organizations) in every configtx profile used to create orderer channels","Verify generated genesis blocks with configtxgen -inspectBlock or configtxlator before distribution","Never reuse an application-channel profile to bootstrap an orderer channel","Review config update deltas (configtxlator compare) to confirm the Orderer group is preserved"],"tags":["hyperledger-fabric","orderer","configtx","smartbft"],"backgroundTag":"missing-orderer-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"}