{"record":{"id":"0b87b58406b6ba38","repo":"hyperledger/fabric","slug":"no-peer-combination-can-satisfy-the-endorsement-po","errorCode":null,"errorMessage":"no peer combination can satisfy the endorsement policy","messagePattern":"no peer combination can satisfy the endorsement policy","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/endorsement/endorsement.go","lineNumber":173,"sourceCode":"\tidentitiesOfMembers memberIdentities\n\tchaincodeMapping    map[string]gossipdiscovery.NetworkMember\n}\n\nfunc (ea *endorsementAnalyzer) computeEndorsementResponse(ctx *context) (*discovery.EndorsementDescriptor, error) {\n\t// mapPrincipalsToGroups returns a mapping from principals to their corresponding groups.\n\t// groups are just human readable representations that mask the principals behind them\n\tprincipalGroups := mapPrincipalsToGroups(ctx.principalsSets)\n\t// principalsToPeersGraph computes a bipartite graph (V1 U V2 , E)\n\t// such that V1 is the peers, V2 are the principals,\n\t// and each e=(peer,principal) is in E if the peer satisfies the principal\n\tsatGraph := principalsToPeersGraph(principalAndPeerData{\n\t\tmembers: ctx.aliveMembership,\n\t\tpGrps:   principalGroups,\n\t}, ea.satisfiesPrincipal(ctx.channel, ctx.identitiesOfMembers))\n\n\tlayouts := computeLayouts(ctx.principalsSets, principalGroups, satGraph)\n\tif len(layouts) == 0 {\n\t\treturn nil, errors.New(\"no peer combination can satisfy the endorsement policy\")\n\t}\n\n\tcriteria := &peerMembershipCriteria{\n\t\tpossibleLayouts:  layouts,\n\t\tsatGraph:         satGraph,\n\t\tchanMemberById:   ctx.channelMembersById,\n\t\tidOfMembers:      ctx.identitiesOfMembers,\n\t\tchaincodeMapping: ctx.chaincodeMapping,\n\t}\n\n\tgroupToEndorserListMapping := endorsersByGroup(criteria)\n\tlayouts = filterOutUnsatisfiedLayouts(groupToEndorserListMapping, layouts)\n\n\tif len(layouts) == 0 {\n\t\treturn nil, errors.New(\"required chaincodes are not installed on sufficient peers\")\n\t}\n\n\treturn &discovery.EndorsementDescriptor{","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/endorsement/endorsement.go#L155-L191","documentation":"Discovery computes layouts: combinations of peer groups that jointly satisfy the chaincode's endorsement policy principals. If computeLayouts cannot produce any combination from the current alive membership that satisfies the policy, no valid endorsement is possible from the visible network and this error is returned in the EndorsementDescriptor.","triggerScenarios":"Endorsement policy requires organizations whose peers are all down/not in gossip membership; policy principals (e.g. OR of MSP roles) that no alive peer satisfies; channel membership too small for the policy.","commonSituations":"Partners' peers offline so cross-org policies can't be satisfied; peer joined to channel lacking required orgs; endorsement policy updated to require an org not on the channel; gossip bootstrap issues leaving local peer's view incomplete.","solutions":["Ensure at least one peer of every organization required by the policy is running and joined to the channel","Revise the endorsement policy (e.g. OR('Org1MSP.peer','Org2MSP.peer')) to match actual channel membership","Check gossip connectivity so the peer's aliveMembership view includes the needed peers","Re-request discovery after peers recover"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// verify required orgs have alive peers before discovery\nfor _, org := range policyOrgs {\n    if !peerDiscoveryReportsAlivePeer(org) {\n        return fmt.Errorf(\"org %s has no alive peers; policy cannot be satisfied\", org)\n    }\n}","typeGuard":null,"tryCatchPattern":"desc, err := client.PeersForEndorsement(req)\nif err != nil {\n    if strings.Contains(err.Error(), \"no peer combination\") {\n        // fall back to static endorsement peers from connection profile\n        return staticEndorsers, nil\n    }\n    return nil, err\n}","preventionTips":["Monitor gossip membership so org peer outages are alerted early","Design endorsement policies as OR across orgs to tolerate outages","Ensure all policy orgs are actually members of the channel","Retry discovery with backoff during transient gossip convergence"],"tags":["discovery","endorsement-policy","gossip"],"backgroundTag":"endorsement-policy-unsatisfiable","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}