{"record":{"id":"59452936697af6b2","repo":"hyperledger/fabric","slug":"collection-name-s-contains-an-identity-that-i","errorCode":null,"errorMessage":"collection-name: %s -- contains an identity that is not part of the channel","messagePattern":"collection-name: (.+?) -- contains an identity that is not part of the channel","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/lifecycle/scc.go","lineNumber":891,"sourceCode":"\t\t\t\treturn errors.Errorf(\"collection-name: %s -- collection member '%s' is not part of the channel\", coll.GetName(), orgID)\n\t\t\t}\n\n\t\tcase mspprotos.MSPPrincipal_ORGANIZATION_UNIT:\n\t\t\tmspou := &mspprotos.OrganizationUnit{}\n\t\t\terr := proto.Unmarshal(principal.Principal, mspou)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"collection-name: %s -- cannot unmarshal identity bytes into OrganizationUnit\", coll.GetName())\n\t\t\t}\n\t\t\torgID = mspou.MspIdentifier\n\t\t\t// the msp map is indexed using msp IDs - this behavior is implementation specific, making the following check a bit of a hack\n\t\t\t_, ok := msps[orgID]\n\t\t\tif !ok {\n\t\t\t\treturn errors.Errorf(\"collection-name: %s -- collection member '%s' is not part of the channel\", coll.GetName(), orgID)\n\t\t\t}\n\n\t\tcase mspprotos.MSPPrincipal_IDENTITY:\n\t\t\tif _, err := mspMgr.DeserializeIdentity(principal.Principal); err != nil {\n\t\t\t\treturn errors.Errorf(\"collection-name: %s -- contains an identity that is not part of the channel\", coll.GetName())\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn errors.Errorf(\"collection-name: %s -- principal type %v is not supported\", coll.GetName(), principal.PrincipalClassification)\n\t\t}\n\t}\n\treturn nil\n}\n\n// validateSpOrConcat checks if the supplied signature policy is just an OR-concatenation of identities\nfunc validateSpOrConcat(sp *common.SignaturePolicy) error {\n\tif sp.GetNOutOf() == nil {\n\t\treturn nil\n\t}\n\t// check if N == 1 (OR concatenation)\n\tif sp.GetNOutOf().N != 1 {\n\t\treturn errors.Errorf(\"signature policy is not an OR concatenation, NOutOf %d\", sp.GetNOutOf().N)\n\t}","sourceCodeStart":873,"sourceCodeEnd":909,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/lifecycle/scc.go#L873-L909","documentation":"For IDENTITY-class principals in a collection member orgs policy, the raw identity bytes are deserialized via the channel's MSP manager. This error is thrown when the bytes are not a valid identity of any channel member, meaning the collection contains an identity outside the channel.","triggerScenarios":"A collection config member_orgs_policy with an MSPPrincipal_IDENTITY whose principal bytes fail mspMgr.DeserializeIdentity during approve/commit validation.","commonSituations":"Raw certificate bytes or base64 strings passed instead of a serialized identity; identity issued by an MSP not on the channel; identity from another network/environment pasted into the collection config.","solutions":["Use identities (serialized identity protobufs) issued by MSPs on the channel.","Prefer ROLE-based principals over raw identities for collection policies.","Verify the identity deserializes against a channel MSP before submitting.","Regenerate the collection config with tooling that produces valid principals."],"exampleFix":"// before\nprincipal := &mspprotos.MSPPrincipal{PrincipalClassification: mspprotos.MSPPrincipal_IDENTITY, Principal: []byte(pemCertString)}\n// after: use a role principal for the peer's org\nrole, _ := proto.Marshal(&mspprotos.MSPRole{MspIdentifier: \"Org1MSP\", Role: mspprotos.MSPRole_PEER})\nprincipal := &mspprotos.MSPPrincipal{PrincipalClassification: mspprotos.MSPPrincipal_ROLE, Principal: role}","handlingStrategy":"validation","validationCode":"for _, p := range policy.Identities {\n  if p.PrincipalClassification == mspprotos.MSPPrincipal_IDENTITY {\n    if _, err := mspMgr.DeserializeIdentity(p.Principal); err != nil {\n      return fmt.Errorf(\"identity principal not valid on channel: %w\", err)\n    }\n  }\n}","typeGuard":"func isChannelIdentity(p *mspprotos.MSPPrincipal, mspMgr msp.MSPManager) bool {\n  if p == nil || p.PrincipalClassification != mspprotos.MSPPrincipal_IDENTITY {\n    return false\n  }\n  _, err := mspMgr.DeserializeIdentity(p.Principal)\n  return err == nil\n}","tryCatchPattern":"if err := approve(...); err != nil {\n  if strings.Contains(err.Error(), \"contains an identity that is not part of the channel\") {\n    // replace raw identity principals with ROLE principals and resubmit\n  }\n  return err\n}","preventionTips":["Avoid IDENTITY principals in collection configs; use ROLE instead.","Never paste PEM certs or base64 strings as principal bytes.","Ensure identities come from MSPs enrolled on this channel/network."],"tags":["fabric","private-data","identity","msp"],"backgroundTag":"identity-not-on-channel","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"}