hyperledger/fabric · error
policy %s at path %s was nil
Error message
policy %s at path %s was nil
What it means
NewManagerImpl builds the runtime policy map from the config tree. If a configured policy entry exists but its embedded Policy proto is nil, the manager cannot construct it and throws this error naming the policy and its config path.
Source
Thrown at common/policies/policy.go:205
_, ok := providers[int32(cb.Policy_IMPLICIT_META)]
if ok {
logger.Panicf("ImplicitMetaPolicy type must be provider by the policy manager")
}
managers := make(map[string]*ManagerImpl)
for groupName, group := range root.Groups {
managers[groupName], err = NewManagerImpl(path+PathSeparator+groupName, providers, group)
if err != nil {
return nil, err
}
}
policies := make(map[string]Policy)
for policyName, configPolicy := range root.Policies {
policy := configPolicy.Policy
if policy == nil {
return nil, fmt.Errorf("policy %s at path %s was nil", policyName, path)
}
var cPolicy Policy
if policy.Type == int32(cb.Policy_IMPLICIT_META) {
imp, err := NewImplicitMetaPolicy(policy.Value, managers)
if err != nil {
return nil, errors.Wrapf(err, "implicit policy %s at path %s did not compile", policyName, path)
}
cPolicy = imp
} else {
provider, ok := providers[policy.Type]
if !ok {
return nil, fmt.Errorf("policy %s at path %s has unknown policy type: %v", policyName, path, policy.Type)
}
var err error
cPolicy, _, err = provider.NewPolicy(policy.Value)View on GitHub (pinned to 2736b63f8f)
Solutions
- Populate the Policy field (type and value) for the named policy in the config
- Regenerate the channel configuration with a correct configtx.yaml profile so every policy entry has a body
- Remove the empty policy entry if it is not needed
Example fix
// before
&cb.ConfigPolicy{Policy: nil}
// after
&cb.ConfigPolicy{Policy: &cb.Policy{Type: int32(cb.Policy_IMPLICIT_META), Value: "ANY Readers"}} Defensive patterns
Strategy: validation
Validate before calling
for name, cp := range configGroup.Policies {
if cp == nil || cp.Policy == nil {
return fmt.Errorf("policy %s has no Policy proto defined", name)
}
} Try / catch
mgr, err := policies.NewManagerImpl(root, path, providers)
if err != nil && strings.Contains(err.Error(), "was nil") {
return fmt.Errorf("channel config contains an empty policy entry: %w", err)
} Prevention
- Never leave a Policy entry without a Type and Value in channel config
- Regenerate config with configtxgen instead of hand-editing protos
- Validate the config tree before submitting channel updates
When it happens
Trigger: Calling NewManagerImpl (directly or via NewBundle) on a config tree where root.Policies contains an entry whose Policy field was never populated, e.g. a placeholder policy group created but not assigned a policy proto.
Common situations: Hand-edited or tool-generated channel config with an empty policy entry; an update transaction that removed the policy body but left the key; configtx template producing an empty policy stanza.
Related errors
- implicit policy %s at path %s did not compile
- failed to deserialize values
- illegal orderer config update detected: endpoints of org %s
- orderer org %s attempted to change MSP ID from %s to %s
- current config has application section, but new config does
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/92d316902efa645c.
Report an issue: GitHub.