hyperledger/fabric · error
no orderer config in config block
Error message
no orderer config in config block
What it means
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.
Source
Thrown at orderer/consensus/smartbft/util.go:299
// remoteNodesFromConfigBlock unmarshalls the node config from the block metadata
func remoteNodesFromConfigBlock(block *cb.Block, logger *flogging.FabricLogger, bccsp bccsp.BCCSP) (*nodeConfig, error) {
env := &cb.Envelope{}
if err := proto.Unmarshal(block.Data.Data[0], env); err != nil {
return nil, errors.Wrap(err, "failed unmarshalling envelope of config block")
}
bundle, err := channelconfig.NewBundleFromEnvelope(env, bccsp)
if err != nil {
return nil, errors.Wrap(err, "failed getting a new bundle from envelope of config block")
}
channelMSPs, err := bundle.MSPManager().GetMSPs()
if err != nil {
return nil, errors.Wrap(err, "failed obtaining MSPs from MSPManager")
}
oc, ok := bundle.OrdererConfig()
if !ok {
return nil, errors.New("no orderer config in config block")
}
_, err = createSmartBftConfig(oc)
if err != nil {
return nil, err
}
var nodeIDs []uint64
var remoteNodes []cluster.RemoteNode
id2Identies := map[uint64][]byte{}
for _, consenter := range oc.Consenters() {
sanitizedID, err := crypto.SanitizeIdentity(protoutil.MarshalOrPanic(&msp.SerializedIdentity{
IdBytes: consenter.Identity,
Mspid: consenter.MspId,
}))
if err != nil {
logger.Panicf("Failed to sanitize identity: %v [%s]", err, string(consenter.Identity))
}View on GitHub (pinned to 2736b63f8f)
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
Example fix
// before: configtx.yaml profile without orderer section
Profiles:
AppChannel:
Application:
Organizations: [...]
// after
Profiles:
AppChannel:
Orderer:
OrdererType: etcdraft # / smartbft
Organizations:
- *OrdererOrg
Application:
Organizations: [...] Defensive patterns
Strategy: validation
Validate before calling
bundle, err := channelconfig.NewBundleFromEnvelope(env, bccsp)
if err != nil {
return err
}
if _, ok := bundle.OrdererConfig(); !ok {
chID, _ := bundle.ConfigtxValidator().ChannelID(), nil
return fmt.Errorf("channel %s config has no Orderer group; use an orderer-capable configtx profile", chID)
} Type guard
func hasOrdererConfig(bundle *channelconfig.Bundle) bool {
if bundle == nil {
return false
}
_, ok := bundle.OrdererConfig()
return ok
} Try / catch
oc, ok := bundle.OrdererConfig()
if !ok {
return fmt.Errorf("channel %q is not an orderer channel; regenerate genesis block from a profile with an Orderer section", bundle.ConfigtxValidator().ChannelID())
} Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Attempted to set the batch size preferred max bytes (%v) gre
- Attempted to set the batch timeout to a invalid value: %s
- Attempted to set the batch timeout to a non-positive value:
- failed to unmarshal BFT metadata configuration
- invalid BFT metadata configuration
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/c596acd314611710.
Report an issue: GitHub.