hyperledger/fabric · error
ConfigGroup not found at group path: %s
Error message
ConfigGroup not found at group path: %s
What it means
recurseConfigMap found an entry at 'groups/<path>' in the configMap, but the entry does not wrap an actual cb.ConfigGroup (comparable.ConfigGroup is nil). The comparable type is a union of ConfigGroup/ConfigValue/ConfigPolicy, so this means the wrong kind of element was stored under a group path.
Source
Thrown at common/configtx/configmap.go:120
// configMapToConfig is intended to be called from outside this file
// It takes a configMap and converts it back into a *cb.ConfigGroup structure
func configMapToConfig(configMap map[string]comparable, rootGroupKey string) (*cb.ConfigGroup, error) {
rootPath := pathSeparator + rootGroupKey
return recurseConfigMap(rootPath, configMap)
}
// recurseConfigMap is used only internally by configMapToConfig
// Note, this function no longer mutates the cb.Config* entries within configMap
func recurseConfigMap(path string, configMap map[string]comparable) (*cb.ConfigGroup, error) {
groupPath := groupPrefix + path
group, ok := configMap[groupPath]
if !ok {
return nil, errors.Errorf("missing group at path: %s", groupPath)
}
if group.ConfigGroup == nil {
return nil, errors.Errorf("ConfigGroup not found at group path: %s", groupPath)
}
newConfigGroup := protoutil.NewConfigGroup()
proto.Merge(newConfigGroup, group.ConfigGroup)
for key := range group.Groups {
updatedGroup, err := recurseConfigMap(path+pathSeparator+key, configMap)
if err != nil {
return nil, err
}
newConfigGroup.Groups[key] = updatedGroup
}
for key := range group.Values {
valuePath := valuePrefix + path + pathSeparator + key
value, ok := configMap[valuePath]
if !ok {
return nil, errors.Errorf("missing value at path: %s", valuePath)View on GitHub (pinned to 2736b63f8f)
Solutions
- Fix the map construction so every 'groups/<path>' key holds comparable{ConfigGroup: ...}.
- Regenerate the map with configtx.NewComparableConfig to guarantee path/prefix consistency.
- Check constants groupPrefix/valuePrefix/policyPrefix usage if building keys manually — the prefix must match the payload kind.
- Log the comparable at the reported path and correct the wrong kind stored there.
Example fix
// before
configMap["groups/Application"] = comparable{ConfigValue: someValue}
// after
configMap["groups/Application"] = comparable{ConfigGroup: appGroup} Defensive patterns
Strategy: validation
Validate before calling
func groupEntryIsGroup(configMap map[string]configtx.Comparable, path string) bool {
c, ok := configMap["groups/"+path]
return ok && c.ConfigGroup != nil
} Type guard
func asConfigGroup(c comparable) (*cb.ConfigGroup, bool) {
if c.ConfigGroup == nil {
return nil, false
}
return c.ConfigGroup, true
} Try / catch
// errors are returned, not panicked
config, err := configtx.ConfigMapToConfig(configMap)
if err != nil {
return fmt.Errorf("non-group payload under group path: %w", err)
} Prevention
- Match the comparable union member to the key prefix (groups/ -> ConfigGroup)
- Let NewComparableConfig derive keys and payloads together
- Add map invariants tests asserting kind/prefix consistency before conversion
When it happens
Trigger: recurseConfigMap encountering a configMap entry keyed as a group whose comparable has ConfigGroup == nil — e.g. a ConfigValue or ConfigPolicy stored under a 'groups/...' key, or a zero-value comparable inserted by buggy map construction.
Common situations: Hand-built maps with path/prefix confusion (groupPrefix vs valuePrefix); deserialization that left the ConfigGroup unset; tests seeding placeholder comparables without payloads.
Related errors
- missing group at path: %s
- Attempted to set the batch size max message count to an inva
- Attempted to set the batch size absolute max bytes to an inv
- Attempted to set the batch size preferred max bytes to an in
- Attempted to set the batch size preferred max bytes (%v) gre
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/4b020b9ca0e6cc3f.
Report an issue: GitHub.