{"record":{"id":"c8d3407a3d04b5dd","repo":"hyperledger/fabric","slug":"failed-verifying-that-the-signed-data-identity-sat","errorCode":null,"errorMessage":"failed verifying that the signed data identity satisfies local MSP principal during channelless check policy with policy [%s]: [%s]","messagePattern":"failed verifying that the signed data identity satisfies local MSP principal during channelless check policy with policy \\[(.+?)\\]: \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/policy/policy.go","lineNumber":218,"sourceCode":"\tfor _, data := range signedData {\n\t\t// Deserialize identity with the local MSP\n\t\tid, err := p.localMSP.DeserializeIdentity(data.Identity)\n\t\tif err != nil {\n\t\t\tlogger.Warnw(\"Failed deserializing signed data identity during channelless check policy\", \"error\", err, \"policyName\", policyName, \"identity\", protoutil.LogMessageForSerializedIdentity(data.Identity))\n\t\t\treturn fmt.Errorf(\"failed deserializing signed data identity during channelless check policy with policy [%s]: [%s]\", policyName, err)\n\t\t}\n\n\t\t// Load MSPPrincipal for policy\n\t\tprincipal, err := p.principalGetter.Get(policyName)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed getting local MSP principal during channelless check policy with policy [%s]: [%s]\", policyName, err)\n\t\t}\n\n\t\t// Verify that proposal's creator satisfies the principal\n\t\terr = id.SatisfiesPrincipal(principal)\n\t\tif err != nil {\n\t\t\tlogger.Warnw(\"failed verifying that the signed data identity satisfies local MSP principal during channelless check policy\", \"error\", err, \"policyName\", policyName, \"requiredPrincipal\", principal, \"identity\", protoutil.LogMessageForSerializedIdentity(data.Identity))\n\t\t\treturn fmt.Errorf(\"failed verifying that the signed data identity satisfies local MSP principal during channelless check policy with policy [%s]: [%s]\", policyName, err)\n\t\t}\n\n\t\t// Verify the signature\n\t\tif err = id.Verify(data.Data, data.Signature); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":200,"sourceCodeEnd":229,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/policy/policy.go#L200-L229","documentation":"CheckPolicyNoChannelBySignedData evaluates a channelless (local-MSP) policy against signed data. For each SignedData it deserializes the identity with the local MSP and calls id.SatisfiesPrincipal(principal) — the principal being 'Admins' or 'Members' resolved from policyName. This error is returned when the identity is valid for the local MSP but does not satisfy the required principal role (e.g. the signer is a Member but the check required Admins).","triggerScenarios":"Calling CheckPolicyNoChannelBySignedData with a policyName of 'Admins' (or 'Members') where the signer's identity belongs to the local MSP but is not in that role: e.g. a non-admin peer or client signs a system-chaincode proposal (like a cscc JoinChain) while local policy requires Admins; also when the identity was serialized by a different MSP than the node's local MSP.","commonSituations":"A client uses its admin cert from an organization whose MSP differs from the peer's local MSP; admin certs were rotated/regenerated and the old cert no longer satisfies the Admins principal; the caller signs with a TLS cert or member enrollment cert instead of the admin cert; network migration changed MSP IDs so deserialization succeeds via a different path but role membership fails.","solutions":["Sign the proposal with the local MSP admin identity (cryptogen/fabric-ca admin signer for the peer's organization)","Verify the signer's MSP ID matches the peer's local MSP (core.yaml peer.localMspId / MSP config) and that the cert is present in the local MSP admincerts directory","If Members suffices, pass policyName 'Members' instead of 'Admins','or re-enroll/regenerate the admin certificate and restart the peer so the local MSP picks it up"],"exampleFix":"// before\nsigner, _ := mspMgr.GetDefaultSigningIdentity() // member cert\nerr := checker.CheckPolicyNoChannelBySignedData(\"Admins\", signedData)\n// after\nadminSigner, _ := adminSignerForLocalMSP(localMSP) // load admincerts-based signing identity\nerr := checker.CheckPolicyNoChannelBySignedData(\"Admins\", signedData)","handlingStrategy":"validation","validationCode":"func canSignAsLocalAdmin(signer msp.SigningIdentity, localMSP msp.MSP) error {\n    principal, err := policy.NewLocalMSPPrincipalGetter(localMSP).Get(\"Admins\")\n    if err != nil { return err }\n    idBytes, _ := signer.Serialize()\n    id, err := localMSP.DeserializeIdentity(idBytes)\n    if err != nil { return fmt.Errorf(\"signer not in local MSP: %w\", err) }\n    return id.SatisfiesPrincipal(principal)\n}","typeGuard":"func isLocalMSPIdentity(localMSP msp.MSP, serializedID []byte) bool {\n    _, err := localMSP.DeserializeIdentity(serializedID)\n    return err == nil\n}","tryCatchPattern":"if err := checker.CheckPolicyNoChannelBySignedData(policyName, signedData); err != nil {\n    if strings.Contains(err.Error(), \"satisfies local MSP principal\") {\n        // authorization problem: switch to an admin signer, do not retry\n        return fmt.Errorf(\"signer lacks required local role %s: %w\", policyName, err)\n    }\n    return err\n}","preventionTips":["Always sign channelless system-chaincode proposals with the local MSP admin identity","Keep the peer's local MSP admincerts in sync with the certificates actually used to sign","Confirm signer MSP ID matches peer.localMspId before submitting","Log protoutil.LogMessageForSerializedIdentity in tests to catch wrong-cert mistakes early"],"tags":["hyperledger-fabric","msp","authorization","policy"],"backgroundTag":"msp-principal-check-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"}