{"record":{"id":"fc72bb2c638859a7","repo":"hyperledger/fabric","slug":"no-orderer-config","errorCode":null,"errorMessage":"no orderer config","messagePattern":"no orderer config","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"orderer/consensus/smartbft/util.go","lineNumber":116,"sourceCode":"}\n\nfunc configBlockToBFTConfig(selfID uint64, block *cb.Block, bccsp bccsp.BCCSP) (types.Configuration, error) {\n\tif block == nil || block.Data == nil || len(block.Data.Data) == 0 {\n\t\treturn types.Configuration{}, errors.New(\"empty block\")\n\t}\n\n\tenv, err := protoutil.UnmarshalEnvelope(block.Data.Data[0])\n\tif err != nil {\n\t\treturn types.Configuration{}, err\n\t}\n\tbundle, err := channelconfig.NewBundleFromEnvelope(env, bccsp)\n\tif err != nil {\n\t\treturn types.Configuration{}, err\n\t}\n\n\toc, ok := bundle.OrdererConfig()\n\tif !ok {\n\t\treturn types.Configuration{}, errors.New(\"no orderer config\")\n\t}\n\n\tconsensusConfigOptions, err := createSmartBftConfig(oc)\n\tif err != nil {\n\t\treturn types.Configuration{}, err\n\t}\n\n\treturn util.ConfigFromMetadataOptions(selfID, consensusConfigOptions)\n}\n\nfunc getViewMetadataFromBlock(block *cb.Block) (*smartbftprotos.ViewMetadata, error) {\n\tif block.Header.Number == 0 {\n\t\t// Genesis block has no prior metadata so we just return an un-initialized metadata\n\t\treturn new(smartbftprotos.ViewMetadata), nil\n\t}\n\n\tsignatureMetadata := protoutil.GetMetadataFromBlockOrPanic(block, cb.BlockMetadataIndex_SIGNATURES)\n\tordererMD := &cb.OrdererBlockMetadata{}","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/util.go#L98-L134","documentation":"After decoding the config envelope and building a config bundle, configBlockToBFTConfig calls bundle.OrdererConfig(); if the bundle has no Orderer group it returns 'no orderer config'. A BFT consenter can only derive its types.Configuration from a channel config that contains an Orderer section.","triggerScenarios":"Committing a config block whose channel config lacks the orderer group (e.g. an application-channel update that removed the Orderer section, or a block that is not actually a channel config).","commonSituations":"Channel update accidentally deleting the Orderer group via configtxlator round-trip, applying a config block from the wrong channel, or system-channel/channel config confusion.","solutions":["Ensure the committed block is a valid channel config containing the Orderer group","Re-issue the channel update including the Orderer section with the consenter list","Verify with configtxlator/inspect that the new config JSON has an 'orderer' group before submitting","Restore the previous good config block if the update was erroneous"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"bundle, _ := channelconfig.NewBundleFromEnvelope(env)\nif _, ok := bundle.OrdererConfig(); !ok {\n  return errors.New(\"proposed config block lacks an Orderer group; aborting\")\n}","typeGuard":null,"tryCatchPattern":"if err := chain.BlockCommitted(block); err != nil && strings.Contains(err.Error(), \"no orderer config\") {\n  logger.Errorf(\"channel update removed orderer config; roll back: %v\", err)\n}","preventionTips":["Diff proposed channel config JSON against current config before submission","Never remove the Orderer group in config updates","Confirm the block originates from the correct channel","Use configtxlator decode/encode round-trips to detect dropped groups"],"tags":["hyperledger-fabric","smartbft","channel-config"],"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"}