hyperledger/fabric · error

ConfigValue not found at value path: %s

Error message

ConfigValue not found at value path: %s

What it means

When a 'values/<path>/<key>' entry is found, its comparable must wrap a real cb.ConfigValue. This error means the entry exists under a value path but comparable.ConfigValue is nil — the wrong union member (or an empty comparable) was stored at that key. It is thrown immediately before cloning the value into the reconstructed ConfigGroup.

Source

Thrown at common/configtx/configmap.go:141

	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)
		}
		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

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Store comparable{ConfigValue: ...} for every 'values/...' key in the map.
  2. Prefer configtx.NewComparableConfig over manual map construction to keep kinds and prefixes aligned.
  3. Audit any helper that builds comparables and assert the payload kind matches the key prefix.
  4. Dump the comparable at the reported path to identify which wrong member was set.

Example fix

// before
configMap["values/Orderer/values/BatchSize"] = comparable{ConfigPolicy: policy}
// after
configMap["values/Orderer/values/BatchSize"] = comparable{ConfigValue: batchSizeValue}
Defensive patterns

Strategy: validation

Validate before calling

func valueEntryIsValue(configMap map[string]configtx.Comparable, path, key string) bool {
	c, ok := configMap["values/"+path+"/"+key]
	return ok && c.ConfigValue != nil
}

Type guard

func asConfigValue(c comparable) (*cb.ConfigValue, bool) {
	if c.ConfigValue == nil {
		return nil, false
	}
	return c.ConfigValue, true
}

Try / catch

// errors are returned, not panicked
config, err := configtx.ConfigMapToConfig(configMap)
if err != nil {
	return fmt.Errorf("non-value payload under value path: %w", err)
}

Prevention

When it happens

Trigger: recurseConfigMap finding a configMap entry at the computed valuePath whose ConfigValue field is nil — e.g. a ConfigGroup or ConfigPolicy stored under a 'values/...' key, or a zero-value comparable placeholder.

Common situations: Prefix/kind mismatches when constructing the map manually; code that inserts comparables without setting the payload; shared map building utilities reused across kinds with wrong arguments.

Related errors


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