hyperledger/fabric · critical
could not find policy %s
Error message
could not find policy %s
What it means
Returned by chainACL.Evaluate when the channel's policy manager cannot resolve the ChannelWriters policy needed to authorize writers. Evaluate guards message submission on BFT channels; without the policy it cannot verify the signature set, so it fails closed. Normally this wraps ErrPermissionDenied for evaluation failures.
Source
Thrown at orderer/consensus/smartbft/chain.go:660
AccessController: &chainACL{
policyManager: policyManager,
Logger: logger,
},
Ledger: support,
}
}
type chainACL struct {
policyManager policies.Manager
Logger *flogging.FabricLogger
}
// Evaluate evaluates signed data
func (c *chainACL) Evaluate(signatureSet []*protoutil.SignedData) error {
policy, ok := c.policyManager.GetPolicy(policies.ChannelWriters)
if !ok {
return fmt.Errorf("could not find policy %s", policies.ChannelWriters)
}
err := policy.EvaluateSignedData(signatureSet)
if err != nil {
c.Logger.Debugf("SigFilter evaluation failed: %s, policyName: %s", err.Error(), policies.ChannelWriters)
return errors.Wrap(errors.WithStack(msgprocessor.ErrPermissionDenied), err.Error())
}
return nil
}
View on GitHub (pinned to 2736b63f8f)
Solutions
- Verify the channel config (configtx.yaml) defines the Orderer/'Writers' policy (ChannelWriters) in the genesis block
- Restart the orderer so the channel config chain fully loads before accepting submits
- Restore the Writers policy via a config update if a recent update removed it
- Check policyManager initialization order — Evaluate should not be reachable before policies are registered
Example fix
// before
// genesis created without Writers policy -> could not find policy /Channel/Writers
// after
# configtx.yaml
Orderer: &OrdererDefaults
Policies:
Writers:
Type: ImplicitMeta
Rule: "ANY Admins" Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: verify the channel's policy manager resolves Writers before submitting
pm := policyManagerForChannel(chID)
if _, ok := pm.GetPolicy(policies.ChannelWriters); !ok {
return fmt.Errorf("channel %s missing %s policy; check genesis/config", chID, policies.ChannelWriters)
} Type guard
func hasWritersPolicy(pm policies.Manager) bool {
_, ok := pm.GetPolicy(policies.ChannelWriters)
return ok
} Try / catch
if err := chainACL.Evaluate(sigSet); err != nil {
if strings.Contains(err.Error(), "could not find policy") {
// config not loaded or policy removed: reload channel config or fail fast
return fmt.Errorf("channel policy unavailable: %w", err)
}
if errors.Is(err, msgprocessor.ErrPermissionDenied) {
return fmt.Errorf("caller not authorized as writer: %w", err)
}
return err
} Prevention
- Ensure configtx.yaml defines Writers (ImplicitMeta ANY Admins or explicit signature policy) for both Orderer and Application groups
- Never hand-edit or regenerate genesis blocks without policy sections
- Confirm orderer finishes channel config replay before accepting submits
- Audit config updates for accidental policy removal before applying them
When it happens
Trigger: Order/Configure path invokes Evaluate with a signature set while the channel's policy manager lacks the 'Writers' policy — e.g. channel config not fully loaded at startup, or a config update removed/renamed the Writers policy.
Common situations: Orderer starting before the channel's config chain is replayed; corrupted or hand-edited channel config missing Application/Orderer Writers policy; genesis block created with malformed policy definitions; config update that accidentally deleted the Writers policy.
Related errors
- signature set did not satisfy policy
- error authorizing update: %s
- Unmapped policy for %s
- Unknown id on checkACL %s
- Unmapped channelless policy for %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/d082d7e6a21c055b.
Report an issue: GitHub.