hyperledger/fabric · error
ConfigPolicy not found at policy path: %s
Error message
ConfigPolicy not found at policy path: %s
What it means
The config map contained an entry at the policy path, but its ConfigPolicy field was nil. recurseConfigMap requires the map value to be a Config entry carrying a ConfigPolicy to clone into the new group.
Source
Thrown at common/configtx/configmap.go:153
valuePath := valuePrefix + path + pathSeparator + key
value, ok := configMap[valuePath]
if !ok {
return nil, errors.Errorf("missing value at path: %s", valuePath)
}
if value.ConfigValue == nil {
return nil, errors.Errorf("ConfigValue not found at value path: %s", valuePath)
}
newConfigGroup.Values[key] = proto.Clone(value.ConfigValue).(*cb.ConfigValue)
}
for key := range group.Policies {
policyPath := policyPrefix + path + pathSeparator + key
policy, ok := configMap[policyPath]
if !ok {
return nil, errors.Errorf("missing policy at path: %s", policyPath)
}
if policy.ConfigPolicy == nil {
return nil, errors.Errorf("ConfigPolicy not found at policy path: %s", policyPath)
}
newConfigGroup.Policies[key] = proto.Clone(policy.ConfigPolicy).(*cb.ConfigPolicy)
logger.Debugf("Setting policy for key %s to %+v", key, group.Policies[key])
}
// This is a really very hacky fix to facilitate upgrading channels which were constructed
// using the channel generation from v1.0 with bugs FAB-5309, and FAB-6080.
// In summary, these channels were constructed with a bug which left mod_policy unset in some cases.
// If mod_policy is unset, it's impossible to modify the element, and current code disallows
// unset mod_policy values. This hack 'fixes' existing config with empty mod_policy values.
// If the capabilities framework is on, it sets any unset mod_policy to 'Admins'.
// This code needs to sit here until validation of v1.0 channels is deprecated from the codebase.
if _, ok := configMap[hackyFixOrdererCapabilities]; ok {
// Hacky fix constants, used in recurseConfigMap
if newConfigGroup.ModPolicy == "" {
logger.Debugf("Performing upgrade of group %s empty mod_policy", groupPath)
newConfigGroup.ModPolicy = hackyFixNewModPolicy
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Verify the map entry at the policy path is a *cb.Config with a non-nil ConfigPolicy field.
- Check the policyPrefix used when inserting entries matches the policyPrefix used during lookup.
- Reconstruct the map using the library's own mapPopulation helpers rather than custom path strings.
Example fix
// before
configMap["/Channel/policies/Admins"] = &Config{ConfigGroup: group} // wrong type
// after
configMap["/Channel/policies/Admins"] = &Config{ConfigPolicy: policy.ConfigPolicy} Defensive patterns
Strategy: validation
Validate before calling
p := configMap[policyPath]
if p == nil || p.ConfigPolicy == nil {
return fmt.Errorf("entry at %s is not a ConfigPolicy", policyPath)
} Type guard
func isConfigPolicy(c interface{}) bool { cfg, ok := c.(*cb.Config); return ok && cfg != nil && cfg.ConfigPolicy != nil } Try / catch
defer func() {
if r := recover(); r != nil { /* handle nil-clone panic */ }
}()
// or on error: log policyPath entry type and fail fast Prevention
- Store each entry under the correct prefix (policy vs value vs group)
- Nil-check ConfigPolicy before inserting into the map
- Unit-test map construction against the canonical path scheme
When it happens
Trigger: The configMap entry at '<policyPrefix><groupPath>/<key>' exists but is a ConfigGroup or ConfigValue entry rather than a ConfigPolicy, so policy.ConfigPolicy is nil.
Common situations: Prefix mismatch when building the map (e.g. policy stored under valuePrefix or groupPrefix), causing a non-policy entry to be found at the policy path.
Related errors
- missing policy at path: %s
- unexpected missing policy %s for item %s
- policy for %s not satisfied
- error validating DeltaSet
- error authorizing update: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/3585c260eded6f7f.
Report an issue: GitHub.