{"record":{"id":"762d147e753c0b93","repo":"hyperledger/fabric","slug":"collection-name-s-cannot-unmarshal-identity-b-762d14","errorCode":null,"errorMessage":"collection-name: %s -- cannot unmarshal identity bytes into OrganizationUnit","messagePattern":"collection-name: (.+?) -- cannot unmarshal identity bytes into OrganizationUnit","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/lifecycle/scc.go","lineNumber":880,"sourceCode":"\n\t\tcase mspprotos.MSPPrincipal_ROLE:\n\t\t\tmsprole := &mspprotos.MSPRole{}\n\t\t\terr := proto.Unmarshal(principal.Principal, msprole)\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"collection-name: %s -- cannot unmarshal identity bytes into MSPRole\", coll.GetName())\n\t\t\t}\n\t\t\torgID = msprole.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_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","sourceCodeStart":862,"sourceCodeEnd":898,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/lifecycle/scc.go#L862-L898","documentation":"For ORGANIZATION_UNIT-class principals in a collection member orgs policy, the principal bytes are unmarshaled into an OrganizationUnit protobuf. This error is thrown when that unmarshal fails, meaning the bytes are not a valid OrganizationUnit message. It indicates a malformed collection signature policy.","triggerScenarios":"A collection config member_orgs_policy principal with classification ORGANIZATION_UNIT whose Principal bytes are not a marshaled OrganizationUnit protobuf.","commonSituations":"Custom policy-building code stuffing raw strings or wrong message types into the Principal field; copying policy bytes between different classification types; corrupted serialized policies.","solutions":["Marshal a proper mspprotos.OrganizationUnit (MspIdentifier, OrganizationalUnitIdentifier, CertifiersIdentifier) and use those bytes.","Prefer ROLE principals, which are simpler and the common pattern for collections.","Validate the generated policy by deserializing it before submitting the chaincode definition.","Regenerate the collection config with standard tooling."],"exampleFix":"// before\nprincipal := &mspprotos.MSPPrincipal{PrincipalClassification: mspprotos.MSPPrincipal_ORGANIZATION_UNIT, Principal: []byte(\"Org1/unit1\")}\n// after\nou, _ := proto.Marshal(&mspprotos.OrganizationUnit{MspIdentifier: \"Org1MSP\", OrganizationalUnitIdentifier: \"unit1\"})\nprincipal := &mspprotos.MSPPrincipal{PrincipalClassification: mspprotos.MSPPrincipal_ORGANIZATION_UNIT, Principal: ou}","handlingStrategy":"validation","validationCode":"if p.PrincipalClassification == mspprotos.MSPPrincipal_ORGANIZATION_UNIT {\n  var ou mspprotos.OrganizationUnit\n  if err := proto.Unmarshal(p.Principal, &ou); err != nil {\n    return fmt.Errorf(\"invalid ORGANIZATION_UNIT principal: %w\", err)\n  }\n}","typeGuard":"func isOUPrincipal(p *mspprotos.MSPPrincipal) (*mspprotos.OrganizationUnit, bool) {\n  if p == nil || p.PrincipalClassification != mspprotos.MSPPrincipal_ORGANIZATION_UNIT {\n    return nil, false\n  }\n  ou := &mspprotos.OrganizationUnit{}\n  if proto.Unmarshal(p.Principal, ou) != nil {\n    return nil, false\n  }\n  return ou, true\n}","tryCatchPattern":"defer func() {\n  if r := recover(); r != nil { /* handle malformed policy construction */ }\n}()\n// or on submission:\nif err := submit(); err != nil {\n  if strings.Contains(err.Error(), \"cannot unmarshal identity bytes into OrganizationUnit\") {\n    // rebuild policy with marshaled OrganizationUnit bytes\n  }\n}","preventionTips":["Always proto.Marshal an OrganizationUnit before placing it in a principal.","Prefer ROLE principals, which cover most collection use cases.","Round-trip (marshal then unmarshal) test policies before submission.","Never reuse principal bytes across different classifications."],"tags":["fabric","private-data","protobuf","collection-config"],"backgroundTag":"protobuf-unmarshal-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"}