{"record":{"id":"24ff38273892ddaf","repo":"hyperledger/fabric","slug":"endorsement-policy-evaluation-failure-might-be-cau","errorCode":null,"errorMessage":"Endorsement policy evaluation failure might be caused by duplicated identities","messagePattern":"Endorsement policy evaluation failure might be caused by duplicated identities","errorType":"validation","errorClass":"VSCCEndorsementPolicyError","httpStatus":null,"severity":"error","filePath":"core/handlers/validation/builtin/v12/validation_logic.go","lineNumber":163,"sourceCode":"\n\tcap, err := protoutil.UnmarshalChaincodeActionPayload(tx.Actions[actionPosition].Payload)\n\tif err != nil {\n\t\tlogger.Errorf(\"VSCC error: GetChaincodeActionPayload failed, err %s\", err)\n\t\treturn policyErr(err)\n\t}\n\n\tsignatureSet, err := vscc.deduplicateIdentity(cap)\n\tif err != nil {\n\t\treturn policyErr(err)\n\t}\n\n\t// evaluate the signature set against the policy\n\terr = vscc.policyEvaluator.Evaluate(policyBytes, signatureSet)\n\tif err != nil {\n\t\tlogger.Warningf(\"Endorsement policy failure for transaction txid=%s, err: %s\", chdr.GetTxId(), err.Error())\n\t\tif len(signatureSet) < len(cap.Action.Endorsements) {\n\t\t\t// Warning: duplicated identities exist, endorsement failure might be cause by this reason\n\t\t\treturn policyErr(errors.New(DUPLICATED_IDENTITY_ERROR))\n\t\t}\n\t\treturn policyErr(fmt.Errorf(\"VSCC error: endorsement policy failure, err: %s\", err))\n\t}\n\n\t// do some extra validation that is specific to lscc\n\tif namespace == \"lscc\" {\n\t\tlogger.Debugf(\"VSCC info: doing special validation for LSCC\")\n\t\terr := vscc.ValidateLSCCInvocation(chdr.ChannelId, env, cap, payl, vscc.capabilities)\n\t\tif err != nil {\n\t\t\tlogger.Errorf(\"VSCC error: ValidateLSCCInvocation failed, err %s\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// checkInstantiationPolicy evaluates an instantiation policy against a signed proposal.","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/handlers/validation/builtin/v12/validation_logic.go#L145-L181","documentation":"When the endorsement policy evaluation fails AND the constructed signature set is smaller than the number of endorsements in the transaction, VSCC concludes that some endorsements carried duplicated identities (which were deduplicated away) and reports this dedicated error instead of the generic policy failure. The transaction is then marked invalid by the policy check.","triggerScenarios":"A transaction whose Action.Endorsements contain two or more endorsements from the SAME identity (same signer), so after dedup the signatureSet has fewer entries than endorsements, and the remaining signatures still fail policy evaluation.","commonSituations":"Misbehaving SDK or gateway retrying endorsement and appending the same signature twice; tests that sign twice with one identity while the policy expects N distinct signers; malicious peers padding endorsement counts with duplicate signatures.","solutions":["Ensure each endorsement in the proposal response is from a distinct identity as required by the policy","Fix client/SDK logic that re-signs and merges duplicate endorsements instead of requesting new signers","If the policy is stricter than the number of available organizations, change the endorsement policy rather than duplicating signers"],"exampleFix":"// before\n// same identity signs twice, both endorsements appended\n endorsements = [sigFromOrgA, sigFromOrgA]\n// after\n// collect signatures from distinct endorsers per policy\nendorsements = [sigFromOrgA, sigFromOrgB]","handlingStrategy":"validation","validationCode":"// client-side check before submitting\nseen := map[string]bool{}\nfor _, e := range res.Action.Endorsements {\n    id := string(e.Endorser)\n    if seen[id] {\n        return fmt.Errorf(\"duplicate endorser identity: %s\", id)\n    }\n    seen[id] = true\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never append the same signer's endorsement twice when aggregating responses","Ensure the endorsement policy requires at most as many orgs as you can collect","Deduplicate by endorser identity when merging proposal responses from multiple peers"],"tags":["go","endorsement-policy","duplicate-identity","vscc"],"backgroundTag":"duplicate-endorser-identity","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"}