hyperledger/fabric · error
config must contain a channel group
Error message
config must contain a channel group
What it means
This error means the config transaction submitted to NewBundle had a nil ChannelGroup. preValidate in common/channelconfig/bundle.go runs first on every new bundle and requires a channel-level config group to exist, since all channel configuration (capabilities, orderer/application/consortium sub-groups) hangs off it. Without it there is nothing to validate or build a bundle from.
Source
Thrown at common/channelconfig/bundle.go:239
configtxManager, err := configtx.NewValidatorImpl(channelID, config, RootGroupKey, policyManager)
if err != nil {
return nil, errors.Wrap(err, "initializing configtx manager failed")
}
return &Bundle{
policyManager: policyManager,
channelConfig: channelConfig,
configtxManager: configtxManager,
}, nil
}
func preValidate(config *cb.Config) error {
if config == nil {
return errors.New("channelconfig Config cannot be nil")
}
if config.ChannelGroup == nil {
return errors.New("config must contain a channel group")
}
if og, ok := config.ChannelGroup.Groups[OrdererGroupKey]; ok {
if _, ok := og.Values[CapabilitiesKey]; !ok {
if _, ok := config.ChannelGroup.Values[CapabilitiesKey]; ok {
return errors.New("cannot enable channel capabilities without orderer support first")
}
if ag, ok := config.ChannelGroup.Groups[ApplicationGroupKey]; ok {
if _, ok := ag.Values[CapabilitiesKey]; ok {
return errors.New("cannot enable application capabilities without orderer support first")
}
}
}
}
return nil
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Regenerate the config from configtxgen/configtxlator so a ChannelGroup is present at the root of cb.Config
- If decoding a ConfigEnvelope, verify the envelope is complete and unmarshals fully (check err from proto.Unmarshal)
- In tests, populate cfg.ChannelGroup = &cb.ConfigGroup{} (plus required values) before calling NewBundle
- Validate the update with `configtxlator proto_decode` before submitting it to the orderer
Example fix
// before
cfg := &cb.Config{Values: map[string]*cb.ConfigValue{}}
bundle, err := channelconfig.NewBundle(cfg, bccsp) // panics into: config must contain a channel group
// after
cfg := &cb.Config{
ChannelGroup: &cb.ConfigGroup{
Values: map[string]*cb.ConfigValue{},
Groups: map[string]*cb.ConfigGroup{},
},
}
bundle, err := channelconfig.NewBundle(cfg, bccsp) Defensive patterns
Strategy: validation
Validate before calling
func validChannelConfig(cfg *cb.Config) bool {
return cfg != nil && cfg.ChannelGroup != nil
}
if !validChannelConfig(cfg) {
return fmt.Errorf("refusing to build bundle: config has no channel group")
}
bundle, err := channelconfig.NewBundle(cfg, bccsp) Type guard
if cg, ok := cfg.ChannelGroup.(*cb.ConfigGroup); ok && cg != nil { /* safe to use cg */ } Try / catch
bundle, err := channelconfig.NewBundle(cfg, bccsp)
if err != nil && strings.Contains(err.Error(), "config must contain a channel group") {
// regenerate config / fix construction and retry once
} Prevention
- Always build configs with configtxgen/configtxlator rather than hand-assembling cb.Config
- Assert ChannelGroup != nil in unit tests before calling NewBundle
- Validate the full ConfigEnvelope unmarshals without error before submission
When it happens
Trigger: Calling NewBundle with a *cb.Config whose ChannelGroup field is nil (or passing a config built without a channel group). preValidate is invoked by NewBundle and anonymous bundle-construction paths, so any bundle creation from a truncated or partially decoded ConfigEnvelope hits it.
Common situations: Hand-crafted or tool-generated config update payloads that only populate an Application or Orderer group at the top level; configtx.yaml output post-processed incorrectly; a marshaled ConfigEnvelope truncated so ChannelGroup fails to unmarshal; tests constructing cb.Config{} directly without ChannelGroup.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- failed to deserialize values
- Disallowed channel group: %s
- error unmarshalling
- error encoding output
- error unmarshalling original config
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/fe6a37851e32911f.
Report an issue: GitHub.