{"record":{"id":"ff0e1d62eea188d2","repo":"hyperledger/fabric","slug":"collection-name-s-principal-type-v-is-not-su","errorCode":null,"errorMessage":"collection-name: %s -- principal type %v is not supported","messagePattern":"collection-name: (.+?) -- principal type (.+?) is not supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/lifecycle/scc.go","lineNumber":895,"sourceCode":"\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}\n\t// recurse into all sub-rules\n\tfor _, rule := range sp.GetNOutOf().Rules {\n\t\terr := validateSpOrConcat(rule)\n\t\tif err != nil {","sourceCodeStart":877,"sourceCodeEnd":913,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/lifecycle/scc.go#L877-L913","documentation":"Collection member orgs policies only support ROLE, ORGANIZATION_UNIT, and IDENTITY principal classifications. This error is thrown when a principal uses any other classification (e.g. ANONYMITY or COMPOSITE).","triggerScenarios":"Submitting a chaincode definition whose collection config member_orgs_policy contains an MSPPrincipal with a classification other than ROLE, ORGANIZATION_UNIT, or IDENTITY.","commonSituations":"Reusing endorsement/signature policies that permit anonymity or composite principals as collection member policies; hand-built policy structs with a zero-value or wrong enum.","solutions":["Rewrite the member orgs policy using only ROLE, ORGANIZATION_UNIT, or IDENTITY principals.","Wrap OR-of-principals via NOutOf(N=1) rules, which are allowed by validateSpOrConcat.","Check for zero-valued PrincipalClassification fields indicating an uninitialized principal.","Use standard collection policy tooling instead of reusing generic signature policies."],"exampleFix":"// before\nprincipal := &mspprotos.MSPPrincipal{PrincipalClassification: mspprotos.MSPPrincipal_ANONYMITY, Principal: anonBytes}\n// after\nrole, _ := proto.Marshal(&mspprotos.MSPRole{MspIdentifier: \"Org1MSP\", Role: mspprotos.MSPRole_MEMBER})\nprincipal := &mspprotos.MSPPrincipal{PrincipalClassification: mspprotos.MSPPrincipal_ROLE, Principal: role}","handlingStrategy":"validation","validationCode":"allowed := map[mspprotos.MSPPrincipal_Classification]bool{\n  mspprotos.MSPPrincipal_ROLE: true,\n  mspprotos.MSPPrincipal_ORGANIZATION_UNIT: true,\n  mspprotos.MSPPrincipal_IDENTITY: true,\n}\nfor _, p := range policy.Identities {\n  if !allowed[p.PrincipalClassification] {\n    return fmt.Errorf(\"principal classification %v not allowed in collection policy\", p.PrincipalClassification)\n  }\n}","typeGuard":"func isCollectionAllowedPrincipal(p *mspprotos.MSPPrincipal) bool {\n  switch p.GetPrincipalClassification() {\n  case mspprotos.MSPPrincipal_ROLE, mspprotos.MSPPrincipal_ORGANIZATION_UNIT, mspprotos.MSPPrincipal_IDENTITY:\n    return true\n  }\n  return false\n}","tryCatchPattern":"if err := commitDefinition(...); err != nil {\n  if strings.Contains(err.Error(), \"principal type\") && strings.Contains(err.Error(), \"is not supported\") {\n    // rewrite policy with supported principal classifications\n  }\n  return err\n}","preventionTips":["Do not reuse endorsement policies as collection member orgs policies.","Check classification enum values after struct literal construction (zero value traps).","Restrict policy builders used for collections to ROLE/OU/IDENTITY."],"tags":["fabric","private-data","collection-config","policy"],"backgroundTag":"unsupported-principal-type","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"}