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

  1. Verify the channel config (configtx.yaml) defines the Orderer/'Writers' policy (ChannelWriters) in the genesis block
  2. Restart the orderer so the channel config chain fully loads before accepting submits
  3. Restore the Writers policy via a config update if a recent update removed it
  4. 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

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


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