hyperledger/fabric · error
policy for %s not satisfied
Error message
policy for %s not satisfied
What it means
verifyDeltaSet rejected the config update because the modification policy for a changed key evaluated the supplied signatures and they did not satisfy it. EvaluateSignedData failed, so the update lacks valid signatures from identities authorized by the item's mod_policy. The wrapped error contains the underlying policy evaluation failure.
Source
Thrown at common/configtx/update.go:99
if value.version() != 0 {
return errors.Errorf("attempted to set key %s to version %d, but key does not exist", key, value.version())
}
continue
}
if value.version() != existing.version()+1 {
return errors.Errorf("attempt to set key %s to version %d, but key is at version %d", key, value.version(), existing.version())
}
policy, ok := vi.policyForItem(existing)
if !ok {
return errors.Errorf("unexpected missing policy %s for item %s", existing.modPolicy(), key)
}
// Ensure the policy is satisfied
if err := policy.EvaluateSignedData(signedData); err != nil {
logger.Warnw("policy not satisfied for channel configuration update", "key", key, "policy", policy, "signingIdenties", protoutil.LogMessageForSerializedIdentities(signedData))
return errors.Wrapf(err, "policy for %s not satisfied", key)
}
}
return nil
}
func verifyFullProposedConfig(writeSet, fullProposedConfig map[string]comparable) error {
for key := range writeSet {
if _, ok := fullProposedConfig[key]; !ok {
return errors.Errorf("writeset contained key %s which did not appear in proposed config", key)
}
}
return nil
}
// authorizeUpdate validates that all modified config has the corresponding modification policies satisfied by the signature set
// it returns a map of the modified config
func (vi *ValidatorImpl) authorizeUpdate(configUpdateEnv *cb.ConfigUpdateEnvelope) (map[string]comparable, error) {
if configUpdateEnv == nil {View on GitHub (pinned to 2736b63f8f)
Solutions
- Collect signatures from identities satisfying the mod_policy of every changed key (typically org Admins) and add them to the ConfigUpdateEnvelope.
- Check the wrapped error to see which policy failed and which key; verify the signing identities belong to the right MSP.
- Ensure certificates used to sign are current (not expired/revoked) and match the MSP config in the channel.
- If the change is unintentional, remove the key from the writeSet so its policy is not evaluated.
- Use `peer channel signconfigtx` for each required org before submitting.
Example fix
// before: submitting update with no/insufficient signatures configUpdateEnv.Signatures = nil // after: sign with an identity satisfying the mod_policy signedEnv, _ := protoutil.CreateSignedEnvelope(...) signedEnv, _ := utils.SignEnvelope(signedEnv, mspID, signer) // or: peer channel signconfigtx -f update.pb
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check signatures cover the required admin policies before submitting
func sufficientSigs(env *cb.ConfigUpdateEnvelope, required int) bool {
return len(env.GetSignatures()) >= required
} Try / catch
if _, err := validator.ProposeConfigUpdate(env, seq); err != nil {
if strings.Contains(err.Error(), "policy for ") && strings.Contains(err.Error(), "not satisfied") {
// gather additional admin signatures and re-sign the envelope
return fmt.Errorf("collect signatures from org admins for changed keys: %w", err)
}
return err
} Prevention
- Use `peer channel signconfigtx` for every org whose Admins policy covers a changed key before submitting.
- Diff the update first and list each changed key's mod_policy to build a signature checklist.
- Rotate MSP certificates proactively; expired admin certs are a top cause of failed policy evaluation.
- For Majority policies, compute the required org count before collecting signatures.
When it happens
Trigger: Calling proposeConfigUpdate or Validate with a ConfigUpdateEnvelope whose writeSet changes keys (adds/updates/removes) whose mod_policy is not satisfied by the signatures in the envelope's signatures field.
Common situations: Submitting an organization-level config change without collecting signatures from the required org admins; missing one org's signature in a multi-org channel; signatures from stale certificates after MSP cert rotation; insufficient signature count for a Majority/Any policy.
Related errors
- error validating DeltaSet
- missing policy at path: %s
- ConfigPolicy not found at policy path: %s
- unexpected missing policy %s for item %s
- error authorizing update: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/41bdc4acd25a1d82.
Report an issue: GitHub.