{"record":{"id":"bff817d4fae70321","repo":"hyperledger/fabric","slug":"implicit-policy-evaluation-failed-d-sub-policie","errorCode":null,"errorMessage":"implicit policy evaluation failed - %d sub-policies were satisfied, but this policy requires %d of the '%s' sub-policies to be satisfied","messagePattern":"implicit policy evaluation failed - (.+?) sub-policies were satisfied, but this policy requires (.+?) of the '(.+?)' sub-policies to be satisfied","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/policies/implicitmeta.go","lineNumber":102,"sourceCode":"\t\t\t\t}\n\t\t\t\tb.WriteString(\"]\")\n\t\t\t\tlogger.Debug(b.String())\n\t\t\t}\n\t\t}\n\t}()\n\n\tfor _, policy := range imp.SubPolicies {\n\t\tif policy.EvaluateSignedData(signatureSet) == nil {\n\t\t\tremaining--\n\t\t\tif remaining == 0 {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\tif remaining == 0 {\n\t\treturn nil\n\t}\n\treturn 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)\n}\n\n// EvaluateIdentities takes an array of identities and evaluates whether\n// they satisfy the policy\nfunc (imp *ImplicitMetaPolicy) EvaluateIdentities(identities []msp.Identity) error {\n\tlogger.Debugf(\"This is an implicit meta policy, it will trigger other policy evaluations, whose failures may be benign\")\n\tremaining := imp.Threshold\n\n\tdefer func() {\n\t\t// This log message may be large and expensive to construct, so worth checking the log level\n\t\tif remaining == 0 {\n\t\t\treturn\n\t\t}\n\t\tif !logger.IsEnabledFor(zapcore.DebugLevel) {\n\t\t\treturn\n\t\t}\n\n\t\tvar b bytes.Buffer","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/policies/implicitmeta.go#L84-L120","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Collect signatures satisfying the required threshold of the named sub-policy (check count and roles)","Verify each signer's identity actually maps to the required sub-policy role via the channel MSP config","Use the reported numbers: satisfied = Threshold-remaining, required = Threshold; add the missing org's signature","If the policy is too strict for your workflow, update the channel policy (e.g. MAJORITY -> ANY) via a proper config update"],"exampleFix":"// before: one admin signature against MAJORITY Admins\nenv, err := createSignedTx(payload, signer1)\n// after: collect enough signatures to meet the threshold\nsigs := []protoutil.Signer{signer1, signer2, signer3} // majority of Admins\nenv, err := createSignedTxWithSignatures(payload, sigs)","handlingStrategy":"try-catch","validationCode":"func signaturesSatisfy(subPolicyName string, threshold int32, sigs []msp.Identity, mgr *policies.ManagerImpl) error {\n\tpol, ok := mgr.GetPolicy(subPolicyName)\n\tif !ok { return fmt.Errorf(\"unknown sub-policy %s\", subPolicyName) }\n\tif err := pol.EvaluateIdentities(sigs); err != nil {\n\t\treturn fmt.Errorf(\"only %d/%d of %s satisfied\", threshold-signatureDeficit(pol, sigs), threshold, subPolicyName)\n\t}\n\treturn nil\n}","typeGuard":"func hasSufficientSignatures(satisfied, required int) bool { return satisfied >= required }","tryCatchPattern":"err := policy.EvaluateSignedData(signedData)\nif err != nil {\n\tvar satisfied, required int\n\tvar name string\n\tif _, 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 {\n\t\tlog.Errorf(\"need %d more signatures for sub-policy '%s'\", required-satisfied, name)\n\t}\n\treturn err\n}","preventionTips":["Count required signatures per the policy rule (ANY/MAJORITY/ALL) before submitting","Verify signers map to the required sub-policy role via channel MSP config","Check endorsement collections match the chaincode endorsement policy","Parse the satisfied/required counts from the error to know exactly what's missing"],"tags":["policies","authorization","endorsement","fabric"],"backgroundTag":"policy-evaluation-failed","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"}