hyperledger/fabric · error

implicit policy evaluation failed - %d sub-policies were sat

Error message

implicit policy evaluation failed - %d sub-policies were satisfied, but this policy requires %d of the '%s' sub-policies to be satisfied

What it means

ImplicitMetaPolicy.EvaluateSignedData counts how many sub-policies are satisfied and requires the configured Threshold of the named sub-policy. If not enough identities/signatures satisfy enough sub-policies (remaining > 0), evaluation fails with this message reporting how many were satisfied vs required.

Source

Thrown at common/policies/implicitmeta.go:102

				}
				b.WriteString("]")
				logger.Debug(b.String())
			}
		}
	}()

	for _, policy := range imp.SubPolicies {
		if policy.EvaluateSignedData(signatureSet) == nil {
			remaining--
			if remaining == 0 {
				return nil
			}
		}
	}
	if remaining == 0 {
		return nil
	}
	return fmt.Errorf("implicit policy evaluation failed - %d sub-policies were satisfied, but this policy requires %d of the '%s' sub-policies to be satisfied", imp.Threshold-remaining, imp.Threshold, imp.SubPolicyName)
}

// EvaluateIdentities takes an array of identities and evaluates whether
// they satisfy the policy
func (imp *ImplicitMetaPolicy) EvaluateIdentities(identities []msp.Identity) error {
	logger.Debugf("This is an implicit meta policy, it will trigger other policy evaluations, whose failures may be benign")
	remaining := imp.Threshold

	defer func() {
		// This log message may be large and expensive to construct, so worth checking the log level
		if remaining == 0 {
			return
		}
		if !logger.IsEnabledFor(zapcore.DebugLevel) {
			return
		}

		var b bytes.Buffer

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Collect signatures satisfying the required threshold of the named sub-policy (check count and roles)
  2. Verify each signer's identity actually maps to the required sub-policy role via the channel MSP config
  3. Use the reported numbers: satisfied = Threshold-remaining, required = Threshold; add the missing org's signature
  4. If the policy is too strict for your workflow, update the channel policy (e.g. MAJORITY -> ANY) via a proper config update

Example fix

// before: one admin signature against MAJORITY Admins
env, err := createSignedTx(payload, signer1)
// after: collect enough signatures to meet the threshold
sigs := []protoutil.Signer{signer1, signer2, signer3} // majority of Admins
env, err := createSignedTxWithSignatures(payload, sigs)
Defensive patterns

Strategy: try-catch

Validate before calling

func signaturesSatisfy(subPolicyName string, threshold int32, sigs []msp.Identity, mgr *policies.ManagerImpl) error {
	pol, ok := mgr.GetPolicy(subPolicyName)
	if !ok { return fmt.Errorf("unknown sub-policy %s", subPolicyName) }
	if err := pol.EvaluateIdentities(sigs); err != nil {
		return fmt.Errorf("only %d/%d of %s satisfied", threshold-signatureDeficit(pol, sigs), threshold, subPolicyName)
	}
	return nil
}

Type guard

func hasSufficientSignatures(satisfied, required int) bool { return satisfied >= required }

Try / catch

err := policy.EvaluateSignedData(signedData)
if err != nil {
	var satisfied, required int
	var name string
	if _, ferr := fmt.Sscanf(err.Error(), "implicit policy evaluation failed - %d sub-policies were satisfied, but this policy requires %d of the '%s'", &satisfied, &required, &name); ferr == nil {
		log.Errorf("need %d more signatures for sub-policy '%s'", required-satisfied, name)
	}
	return err
}

Prevention

When it happens

Trigger: Submitting a transaction/channel update whose signatures satisfy fewer sub-policies than the implicit meta policy threshold requires — e.g. policy 'MAJORITY Admins' with only a minority of admin signatures, 'ANY Readers' evaluated with only non-Reader identities, or signatures from the wrong organization.

Common situations: Endorsement sets that don't match the channel endorsement policy; channel update proposals signed by insufficient orgs; MSP/organization misconfiguration so valid identities resolve to the wrong role; lifecycle operations (chaincode approve/commit) with too few approvals.

Related errors


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