hyperledger/fabric · error
key Config.ChannelGroup.Groups[%s].Groups is nil
Error message
key Config.ChannelGroup.Groups[%s].Groups is nil
What it means
This error comes from Hyperledger Fabric's discovery service config validation (ValidateConfig in discovery/support/config/support.go). When building a channel config from a protobuf Config, the code iterates over the Orderer and Application group keys and requires each ConfigGroup to exist AND to have a non-nil sub-Groups map. A nil Groups map means the channel config was built without proper Orderer/Application sub-groups, so discovery cannot parse the channel hierarchy.
Source
Thrown at discovery/support/config/support.go:242
return nil
}
func ValidateConfig(c *common.Config) error {
if c.ChannelGroup == nil {
return errors.New("field Config.ChannelGroup is nil")
}
grps := c.ChannelGroup.Groups
if grps == nil {
return errors.New("field Config.ChannelGroup.Groups is nil")
}
for _, field := range []string{channelconfig.OrdererGroupKey, channelconfig.ApplicationGroupKey} {
grp, exists := grps[field]
if !exists {
return fmt.Errorf("key Config.ChannelGroup.Groups[%s] is missing", field)
}
if grp.Groups == nil {
return fmt.Errorf("key Config.ChannelGroup.Groups[%s].Groups is nil", field)
}
}
if c.ChannelGroup.Values == nil {
return errors.New("field Config.ChannelGroup.Values is nil")
}
return nil
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure the Config is produced by the standard channel config toolchain (configtxgen / channel config update flow) so Orderer and Application groups each contain a populated Groups map
- If constructing common.Config manually, initialize grp.Groups = map[string]*common.ConfigGroup{} (with required sub-groups) instead of leaving it nil
- Validate the serialized channel config block with configtxlator before feeding it to the discovery support
Example fix
// before
grp, _ := cfg.ChannelGroup.Groups[channelconfig.ApplicationGroupKey]
grp.Values = ...
// Groups left nil
// after
grp, _ := cfg.ChannelGroup.Groups[channelconfig.ApplicationGroupKey]
if grp.Groups == nil {
grp.Groups = make(map[string]*common.ConfigGroup)
}
grp.Groups["MyOrg"] = &common.ConfigGroup{Groups: map[string]*common.ConfigGroup{}, ...} Defensive patterns
Strategy: validation
Validate before calling
func hasGroups(cfg *common.Config) bool {
if cfg == nil || cfg.ChannelGroup == nil || cfg.ChannelGroup.Groups == nil {
return false
}
for _, k := range []string{"Orderer", "Application"} {
g, ok := cfg.ChannelGroup.Groups[k]
if !ok || g == nil || g.Groups == nil {
return false
}
}
return true
}
// if !hasGroups(cfg) { fix config before ValidateConfig } Type guard
func grp, ok := cfg.ChannelGroup.Groups["Orderer"]; ok && grp != nil && grp.Groups != nil; grp
Prevention
- Always generate channel configs via configtxgen instead of hand-assembling protobufs
- Run configtxlator decode/validate on configs before use
- When building ConfigGroup literals, always initialize the Groups map
When it happens
Trigger: Calling ValidateConfig (directly or via NewConfig support construction) with a *common.Config whose ChannelGroup.Groups["Orderer"] or ChannelGroup.Groups["Application"] exists but has Groups == nil — e.g. a config created programmatically that sets the group value but never initializes its nested Groups map, or a config decoded from truncated/malformed channel config bytes.
Common situations: Building channel config protobufs by hand for unit tests or tooling; passing a partial Config (e.g. only Consortiums or only the root group populated) into the discovery support; upgrading Fabric versions and feeding legacy config blobs that lack Orderer/Application sub-groups.
Related errors
- field Config.ChannelGroup.Values is nil
- failed parsing MSPConfig
- invalid consensus type property in config: %v
- malformed org definition for org: %s
- error encode input
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/573db5315da35521.
Report an issue: GitHub.