hyperledger/fabric · error
state based endorsement policy cannot be satisfied
Error message
state based endorsement policy cannot be satisfied
What it means
Thrown by computeStateBasedPrincipalSets when a chaincode's state-based (key-level) endorsement policy produced zero comparable principal sets from SatisfiedBy(), i.e. no combination of principals can ever satisfy the policy. Discovery cannot return any peer group that would fulfill this key-level endorsement requirement, so the request is rejected.
Source
Thrown at discovery/endorsement/endorsement.go:239
if len(chaincode.KeyPolicies) == 0 {
continue
}
logger.Debugf("Chaincode call to %s is satisfied by %d state based policies of %v",
chaincode.Name, len(chaincode.KeyPolicies), chaincode.KeyPolicies)
for _, stateBasedPolicy := range chaincode.KeyPolicies {
var cmpsets inquire.ComparablePrincipalSets
stateBasedPolicy := inquire.NewInquireableSignaturePolicy(stateBasedPolicy)
for _, ps := range stateBasedPolicy.SatisfiedBy() {
cps := inquire.NewComparablePrincipalSet(ps)
if cps == nil {
return nil, errors.New("failed creating a comparable principal set for state based endorsement")
}
cmpsets = append(cmpsets, cps)
}
if len(cmpsets) == 0 {
return nil, errors.New("state based endorsement policy cannot be satisfied")
}
stateBasedCPS = append(stateBasedCPS, cmpsets)
}
}
if len(stateBasedCPS) > 0 {
stateBasedPrincipalSet, err := mergePrincipalSets(stateBasedCPS)
if err != nil {
return nil, errors.WithStack(err)
}
logger.Debugf("Merging state based policies: %v --> %v", stateBasedCPS, stateBasedPrincipalSet)
return stateBasedPrincipalSet, nil
}
logger.Debugf("No state based policies requested")
View on GitHub (pinned to 2736b63f8f)
Solutions
- Review the key-level endorsement policy logic and lower the NOutOf threshold or add principals so it can be satisfied
- Ensure all MSPs referenced by the state-based policy exist on the channel (update channel config)
- Delete/reset the state-based endorsement policy for the affected keys (unset validation parameter)
- If intentionally strict, stop requesting PeersForEndorsement for that chaincode/key combination
Example fix
// before policy := NOutOf(2, principals(len=1)) // unsatisfiable // after policy := NOutOf(1, principals(len=1))
Defensive patterns
Strategy: validation
Validate before calling
policy := inquire.NewInquireableSignaturePolicy(keyPolicy)
if len(policy.SatisfiedBy()) == 0 {
return errors.New("state-based endorsement policy is unsatisfiable")
} Type guard
func satisfiable(p *common.SignaturePolicyEnvelope) bool {
return len(inquire.NewInquireableSignaturePolicy(p).SatisfiedBy()) > 0
} Try / catch
peers, err := client.PeersForEndorsement(ctx, interest)
if err != nil && strings.Contains(err.Error(), "cannot be satisfied") {
// inspect/recreate the key-level policy before retrying
} Prevention
- Ensure NOutOf thresholds never exceed the number of listed principals
- Reference only MSPs defined in channel config
- Clear validation parameters on keys whose policies reference removed orgs
When it happens
Trigger: A KeyPolicy on a chaincode in a ChaincodeInterest inquires to an empty set of satisfying principal combinations — e.g. a signature policy that is logically unsatisfiable (NOutOf threshold exceeding the number of principals, or principals from nonexistent MSPs) or a policy with no satisfying principals.
Common situations: State-based endorsement set with 'OutOf(2, ...)' but only one principal; key-level policies referencing MSP IDs that are not on the channel; policies attached to private data keys whose collections changed.
Related errors
- failed creating a comparable principal set for state based e
- failed creating a comparable principal set
- endorsement policy cannot be satisfied
- policy '%s' must be defined for channel '%s' before chaincod
- policy with reference '%s' on channel '%s' is not convertibl
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/56a028b0e7195993.
Report an issue: GitHub.