{"record":{"id":"71024a056e1b75b1","repo":"hyperledger/fabric","slug":"failed-deserializing-signed-data-identity-during-c","errorCode":null,"errorMessage":"failed deserializing signed data identity during channelless check policy with policy [%s]: [%s]","messagePattern":"failed deserializing signed data identity during channelless check policy with policy \\[(.+?)\\]: \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/policy/policy.go","lineNumber":205,"sourceCode":"}\n\n// CheckPolicyNoChannelBySignedData checks that the passed signed data are valid with the respect to\n// passed policy on the local MSP.\nfunc (p *policyChecker) CheckPolicyNoChannelBySignedData(policyName string, signedData []*protoutil.SignedData) error {\n\tif policyName == \"\" {\n\t\treturn errors.New(\"invalid policy name during channelless check policy. Name must be different from nil.\")\n\t}\n\n\tif len(signedData) == 0 {\n\t\treturn fmt.Errorf(\"no signed data during channelless check policy with policy [%s]\", policyName)\n\t}\n\n\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","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/policy/policy.go#L187-L223","documentation":"This error occurs when the local MSP cannot deserialize one of the identities in the signed data during a channelless policy check. DeserializeIdentity fails when the identity bytes are not a valid marshaled SerializedIdentity, or the certificate chain does not validate against the peer's local MSP (unknown CA, expired cert, wrong MSP). The wrapped inner error after ': [' names the precise MSP reason.","triggerScenarios":"Calling CheckPolicyNoChannelBySignedData with SignedData.Identity that is empty, corrupt, signed by a cert not in the local MSP, or produced by a different Fabric version's identity format; also when the peer's local MSP config lacks the signer's org's root certs.","commonSituations":"Client cert rotated/updated but the peer's MSP folder (admincerts/cacerts) not refreshed; identity bytes taken from the wrong field (e.g. raw cert PEM instead of SerializedIdentity proto); cross-org calls where the caller is enrolled in an MSP the peer doesn't trust; mixing fabric-protos legacy bytes with the new protobuf API.","solutions":["Inspect the wrapped MSP error to distinguish 'unknown CA', 'expired', and 'malformed' cases.","Confirm SignedData.Identity is a marshaled SerializedIdentity (creator from a SignatureHeader), not a raw PEM certificate.","Add the signer organization's root/admin certs to the peer's local MSP configuration and restart/reload MSPs.","Re-enroll or re-sign the data with a currently valid identity from an MSP the peer trusts.","Verify both sides use matching Fabric/protobuf versions so identity serialization is compatible."],"exampleFix":"// before: raw PEM cert used as identity\ndata := &protoutil.SignedData{Data: msg, Identity: certPEM, Signature: sig}\n// after: use the marshaled SerializedIdentity from the signature header\nshdr, _ := protoutil.UnmarshalSignatureHeader(header.SignatureHeader)\ndata := &protoutil.SignedData{Data: msg, Identity: shdr.Creator, Signature: sig}\nerr := policyChecker.CheckPolicyNoChannelBySignedData(\"Admins\", []*protoutil.SignedData{data})","handlingStrategy":"try-catch","validationCode":"// Pre-check: ensure every identity deserializes against the local MSP before the policy call\nfor i, d := range signedData {\n    if _, err := localMSP.DeserializeIdentity(d.Identity); err != nil {\n        return fmt.Errorf(\"signedData[%d] identity not valid for local MSP: %w\", i, err)\n    }\n}","typeGuard":"func hasDeserializableIdentity(localMSP msp.IdentityDeserializer, d *protoutil.SignedData) bool {\n    if d == nil || len(d.Identity) == 0 { return false }\n    _, err := localMSP.DeserializeIdentity(d.Identity)\n    return err == nil\n}","tryCatchPattern":"if err := policyChecker.CheckPolicyNoChannelBySignedData(policyName, signedData); err != nil {\n    if strings.Contains(err.Error(), \"failed deserializing signed data identity\") {\n        cause := err // inner MSP error after ': [' — check for unknown CA / expired cert\n        logger.Warnw(\"identity rejected by local MSP\", \"cause\", cause)\n        return fmt.Errorf(\"signer identity is not trusted by local MSP (update MSP certs?): %v\", err)\n    }\n    return err\n}","preventionTips":["Use the marshaled SerializedIdentity (e.g. from SignatureHeader.Creator), never raw PEM bytes.","Keep the peer's local MSP cacerts/admincerts synchronized with all client organizations' roots.","Watch certificate expiry and rotate identities before they lapse.","Align Fabric and protobuf library versions across client and peer.","Test deserialization of each identity in isolation before running the full policy check."],"tags":["hyperledger-fabric","msp","identity-deserialization","certificate","x509"],"backgroundTag":"identity-deserialization-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"}