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

  1. Verify the map entry at the policy path is a *cb.Config with a non-nil ConfigPolicy field.
  2. Check the policyPrefix used when inserting entries matches the policyPrefix used during lookup.
  3. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/3585c260eded6f7f. Report an issue: GitHub.