{"record":{"id":"644e217b4b2d50c6","repo":"hyperledger/fabric","slug":"signature-set-did-not-satisfy-policy","errorCode":null,"errorMessage":"signature set did not satisfy policy","messagePattern":"signature set did not satisfy policy","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"common/cauthdsl/policy.go","lineNumber":105,"sourceCode":"\tif p == nil {\n\t\treturn errors.New(\"no such policy\")\n\t}\n\n\tids := policies.SignatureSetToValidIdentities(signatureSet, p.deserializer)\n\n\treturn p.EvaluateIdentities(ids)\n}\n\n// EvaluateIdentities takes an array of identities and evaluates whether\n// they satisfy the policy\nfunc (p *policy) EvaluateIdentities(identities []msp.Identity) error {\n\tif p == nil {\n\t\treturn fmt.Errorf(\"No such policy\")\n\t}\n\n\tok := p.evaluator(identities, make([]bool, len(identities)))\n\tif !ok {\n\t\treturn errors.New(\"signature set did not satisfy policy\")\n\t}\n\treturn nil\n}\n\nfunc (p *policy) Convert() (*cb.SignaturePolicyEnvelope, error) {\n\tif p.signaturePolicyEnvelope == nil {\n\t\treturn nil, errors.New(\"nil policy field\")\n\t}\n\n\treturn p.signaturePolicyEnvelope, nil\n}\n","sourceCodeStart":87,"sourceCodeEnd":117,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/cauthdsl/policy.go#L87-L117","documentation":"After the nil guard, EvaluateIdentities runs the compiled evaluator closure over the identity set; if it returns false, the supplied identities do not satisfy the signature policy and this error is returned.","triggerScenarios":"Calling EvaluateIdentities (directly or via EvaluateSignedData) with identities that fail the policy rule — wrong org principals, expired/invalid MSP identities, missing signatures, or an NOutOf threshold not met.","commonSituations":"Endorsement submissions where the endorsing peers' orgs differ from those required by the chaincode policy; identities from an MSP not listed in the policy; signature count below the NOutOf threshold.","solutions":["Audit the signature set against the policy rule (principals, MSP IDs, roles) and obtain the missing valid signatures","Compare the evaluated identities' MSP/OU/role against sigPolicy.Identities","Review the policy definition — it may be stricter (higher N, wrong principals) than intended"],"exampleFix":"// before\nids := []msp.Identity{peerOrgAIdentity} // policy requires majority of {A,B,C}\nerr := pol.EvaluateIdentities(ids) // fails\n// after\nids := []msp.Identity{idA, idB} // satisfies NOutOf(2, {A,B,C})\nerr := pol.EvaluateIdentities(ids)","handlingStrategy":"try-catch","validationCode":"// pre-check: count identities matching the policy principals before evaluating\nsatisfied := countMatchingPrincipals(ids, env.Identities)\nif satisfied < int(env.GetNOutOf().GetN()) {\n    return fmt.Errorf(\"need %d matching identities, have %d\", env.GetNOutOf().GetN(), satisfied)\n}","typeGuard":null,"tryCatchPattern":"if err := pol.EvaluateIdentities(ids); err != nil {\n    if err.Error() == \"signature set did not satisfy policy\" {\n        return fmt.Errorf(\"endorsement rejected: %w (check signers' MSP IDs and policy principals)\", err)\n    }\n    return err\n}","preventionTips":["Log the evaluated signature set (MSP IDs, roles) on rejection for diagnosis","Keep chaincode endorsement policies aligned with collection/private-data policies","Verify identity validity (cert expiry, MSP enrollment) before evaluation"],"tags":["policy","authorization","signature-verification"],"backgroundTag":"signature-set-did-not-satisfy-policy","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"}