hyperledger/fabric · error
no 'Orderer' group in channel groups
Error message
no 'Orderer' group in channel groups
What it means
The SmartBFT consenter checks live under ChannelGroup.Groups["Orderer"]. If that group is absent the verifier cannot read the 'Orderers' value or the BlockValidation policy, so it fails with 'no Orderer group in channel groups'. This is SmartBFT-specific: a BFT channel must have an Orderer group defining its consenter mapping.
Source
Thrown at orderer/consensus/smartbft/configverifier.go:108
return errors.Errorf("unexpected envelope type %s", common.HeaderType_name[chdr.Type])
}
}
func (cbv *ConfigBlockValidator) checkConsentersMatchPolicy(conf *common.Config) error {
if conf == nil {
return fmt.Errorf("empty Config")
}
if conf.ChannelGroup == nil {
return fmt.Errorf("empty channel group")
}
if len(conf.ChannelGroup.Groups) == 0 {
return fmt.Errorf("no groups in channel group")
}
if conf.ChannelGroup.Groups["Orderer"] == nil {
return fmt.Errorf("no 'Orderer' group in channel groups")
}
if len(conf.ChannelGroup.Groups["Orderer"].Values) == 0 {
return fmt.Errorf("no values in 'Orderer' group")
}
if conf.ChannelGroup.Groups["Orderer"].Values["Orderers"] == nil {
return fmt.Errorf("no values in 'Orderer' group")
}
ords := &common.Orderers{}
if err := proto.Unmarshal(conf.ChannelGroup.Groups["Orderer"].Values["Orderers"].Value, ords); err != nil {
return err
}
n := len(ords.ConsenterMapping)
f := (n - 1) / 3
View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure ChannelGroup.Groups contains an "Orderer" group populated by the orderer section of your configtx profile
- Regenerate the channel config with configtxgen using a profile with Orderer: Orderers/ConsensusType set for SmartBFT
- If converting an existing channel, perform the standard consensus-type migration steps so the Orderer group and 'Orderers' value exist
Example fix
// before
Groups: map[string]*common.ConfigGroup{"Application": appGroup} // missing Orderer
// after
Groups: map[string]*common.ConfigGroup{
"Orderer": ordererGroup, // contains Values["Orderers"], Values["ConsensusType"], Policies["BlockValidation"]
"Application": appGroup,
} Defensive patterns
Strategy: validation
Validate before calling
func hasOrdererGroup(conf *common.Config) bool {
return conf != nil && conf.ChannelGroup != nil && conf.ChannelGroup.Groups["Orderer"] != nil
} Type guard
func hasOrdererGroup(c *common.Config) bool {
return c != nil && c.GetChannelGroup() != nil && c.GetChannelGroup().GetGroups()["Orderer"] != nil
} Try / catch
if err := cbv.ValidateConfig(envelope); err != nil {
if strings.Contains(err.Error(), "no 'Orderer' group") {
return fmt.Errorf("not a valid SmartBFT channel config: %w", err)
}
return err
} Prevention
- Use a configtx profile with an Orderer section and SmartBFT consensus when creating BFT channels
- Check Groups["Orderer"] presence (plus Values["Orderers"]) before submitting config updates to a SmartBFT channel
- When migrating consensus types, follow the official migration procedure so the Orderer group is populated
When it happens
Trigger: Validating a SmartBFT channel config whose ChannelGroup.Groups lacks an "Orderer" key — e.g. an application-only config, a config produced for a Raft/Solo channel, or a typo'd group name in generated config.
Common situations: Switching a channel to SmartBFT without regenerating the full orderer config; configtx profiles omitting the Orderer section; tooling that builds the config tree with only Application groups.
Related errors
- invalid BFT metadata configuration
- unexpected envelope type %s
- empty Config
- empty channel group
- no groups in channel group
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/622086abcab481de.
Report an issue: GitHub.