{"record":{"id":"60a26c6caaf3b9f0","repo":"hyperledger/fabric","slug":"could-not-unmarshal-organizationunit-from-principa","errorCode":null,"errorMessage":"could not unmarshal OrganizationUnit from principal","messagePattern":"could not unmarshal OrganizationUnit from principal","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"msp/mspimpl.go","lineNumber":552,"sourceCode":"\tcase m.MSPPrincipal_IDENTITY:\n\t\t// in this case we have to deserialize the principal's identity\n\t\t// and compare it byte-by-byte with our cert\n\t\tprincipalId, err := msp.DeserializeIdentity(principal.Principal)\n\t\tif err != nil {\n\t\t\treturn errors.WithMessage(err, \"invalid identity principal, not a certificate\")\n\t\t}\n\n\t\tif bytes.Equal(id.(*identity).cert.Raw, principalId.(*identity).cert.Raw) {\n\t\t\treturn principalId.Validate()\n\t\t}\n\n\t\treturn errors.New(\"The identities do not match\")\n\tcase m.MSPPrincipal_ORGANIZATION_UNIT:\n\t\t// Principal contains the OrganizationUnit\n\t\tOU := &m.OrganizationUnit{}\n\t\terr := proto.Unmarshal(principal.Principal, OU)\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"could not unmarshal OrganizationUnit from principal\")\n\t\t}\n\n\t\t// at first, we check whether the MSP\n\t\t// identifier is the same as that of the identity\n\t\tif OU.MspIdentifier != msp.name {\n\t\t\treturn errors.Errorf(\"the identity is a member of a different MSP (expected %s, got %s)\", OU.MspIdentifier, id.GetMSPIdentifier())\n\t\t}\n\n\t\t// we then check if the identity is valid with this MSP\n\t\t// and fail if it is not\n\t\terr = msp.Validate(id)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// now we check whether any of this identity's OUs match the requested one\n\t\tfor _, ou := range id.GetOrganizationalUnits() {\n\t\t\tif ou.OrganizationalUnitIdentifier == OU.OrganizationalUnitIdentifier &&","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/msp/mspimpl.go#L534-L570","documentation":"Thrown when an ORGANIZATION_UNIT principal is evaluated: the principal.Principal bytes cannot be unmarshaled into an OrganizationUnit protobuf message. This means the OU principal payload is corrupt, empty, or was serialized with an incompatible schema rather than a mismatch of the OU itself.","triggerScenarios":"Policy evaluation where principal.PrincipalClassification == MSPPrincipal_ORGANIZATION_UNIT and proto.Unmarshal(principal.Principal, &OrganizationUnit{}) fails because the bytes are not a valid serialized OrganizationUnit (e.g. a raw OU name string was stored instead of the marshaled message).","commonSituations":"Hand-crafting endorsement policies and putting a plain OU string into Principal instead of proto.Marshal(&OrganizationUnit{...}); channel config written by an older tool with a changed schema; byte corruption in stored policy definitions.","solutions":["Serialize the OU principal correctly with proto.Marshal(&OrganizationUnit{MspIdentifier: ..., OrganizationalUnitIdentifier: ..., CertifiersIdentifier: ...})","Inspect the policy definition and rebuild it with the fabric-protos OrganizationUnit message rather than raw strings","Verify the protos version used to write the config matches the one linked into the peer"],"exampleFix":"// before: raw string in principal\np := &msp.MSPPrincipal{PrincipalClassification: msp.MSPPrincipal_ORGANIZATION_UNIT, Principal: []byte(\"org1Unit1\")}\n// after: marshaled OrganizationUnit message\nou, _ := proto.Marshal(&msp.OrganizationUnit{MspIdentifier: \"Org1MSP\", OrganizationalUnitIdentifier: \"org1Unit1\"})\np := &msp.MSPPrincipal{PrincipalClassification: msp.MSPPrincipal_ORGANIZATION_UNIT, Principal: ou}","handlingStrategy":"validation","validationCode":"var ou msp.OrganizationUnit\nif err := proto.Unmarshal(principal.Principal, &ou); err != nil {\n\treturn fmt.Errorf(\"OU principal is not a marshaled OrganizationUnit: %w\", err)\n}\nif ou.MspIdentifier == \"\" || ou.OrganizationalUnitIdentifier == \"\" {\n\treturn fmt.Errorf(\"OU principal missing required fields\")\n}","typeGuard":"func isWellFormedOUPrincipal(p *msp.MSPPrincipal) (bool, *msp.OrganizationUnit) {\n\tif p.PrincipalClassification != msp.MSPPrincipal_ORGANIZATION_UNIT {\n\t\treturn false, nil\n\t}\n\tou := &msp.OrganizationUnit{}\n\tif proto.Unmarshal(p.Principal, ou) != nil {\n\t\treturn false, nil\n\t}\n\treturn true, ou\n}","tryCatchPattern":"err := policy.Evaluate(sd)\nif err != nil && strings.Contains(err.Error(), \"could not unmarshal OrganizationUnit\") {\n\t// policy contains malformed OU principal; regenerate it with proto.Marshal\n}","preventionTips":["Never put raw strings in MSPPrincipal.Principal; always store proto.Marshal of the typed message","Round-trip unmarshal every policy you generate before persisting it","Use a single protos version across policy-generation tooling and peers"],"tags":["msp","protobuf","policy","unmarshal"],"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"}