{"record":{"id":"d1816e82fd0e3fce","repo":"hyperledger/fabric","slug":"the-identity-is-not-a-s-under-this-msp-s","errorCode":null,"errorMessage":"The identity is not a [%s] under this MSP [%s]","messagePattern":"The identity is not a \\[(.+?)\\] under this MSP \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"msp/mspimpl.go","lineNumber":528,"sourceCode":"\t\t\treturn msp.Validate(id)\n\t\tcase m.MSPRole_ADMIN:\n\t\t\tmspLogger.Debugf(\"Checking if identity satisfies ADMIN role for %s\", msp.name)\n\t\t\t// in the case of admin, we check that the\n\t\t\t// id is exactly one of our admins\n\t\t\tif msp.isInAdmins(id.(*identity)) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn errors.New(\"This identity is not an admin\")\n\t\tcase m.MSPRole_CLIENT:\n\t\t\tfallthrough\n\t\tcase m.MSPRole_PEER:\n\t\t\tmspLogger.Debugf(\"Checking if identity satisfies role [%s] for %s\", m.MSPRole_MSPRoleType_name[int32(mspRole.Role)], msp.name)\n\t\t\tif err := msp.Validate(id); err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"The identity is not valid under this MSP [%s]\", msp.name)\n\t\t\t}\n\n\t\t\tif err := msp.hasOURole(id, mspRole.Role); err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"The identity is not a [%s] under this MSP [%s]\", m.MSPRole_MSPRoleType_name[int32(mspRole.Role)], msp.name)\n\t\t\t}\n\t\t\treturn nil\n\t\tdefault:\n\t\t\treturn errors.Errorf(\"invalid MSP role type %d\", int32(mspRole.Role))\n\t\t}\n\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\")","sourceCodeStart":510,"sourceCodeEnd":546,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/msp/mspimpl.go#L510-L546","documentation":"Raised after a successful msp.Validate(id) when msp.hasOURole(id, mspRole.Role) fails: the identity is cryptographically valid under the MSP but does not hold the specific OU-based role (CLIENT, PEER, MEMBER, or ADMIN) demanded by the principal. The message names the missing role and MSP.","triggerScenarios":"Policy requires MSPRole_CLIENT or MSPRole_PEER (or MEMBER) and NodeOUs/OUIdentifiers classify the identity's OU as a different type — e.g. a client cert evaluated against a PEER principal, or a peer whose certificate lacks the peer OU when FabricNodeOUs is enabled.","commonSituations":"fabric-ca enrollment without the right OU/type attributes so the cert's OU doesn't map to the required node type; NodeOUs enabled in one org's config but the identity was issued under a different OU structure; mixing legacy admincerts-based MSPs with OU-based role checks; using a peer identity for a client-only policy.","solutions":["Verify the identity certificate's OU matches the required role (decode the cert and check FabricNodeOUs mapping: client, peer, admin, orderer).","Re-enroll the identity from fabric-ca with the correct type/OU (e.g. --enrollment.profile or proper affiliation/type for peer vs client).","Align NodeOUs config (Enable: true and OUIdentifiers) in the MSP config with the OUs actually present in issued certificates.","Or change the policy principal to a role the identity actually holds (e.g. MEMBER instead of CLIENT)."],"exampleFix":"// before: client cert used against PEER principal\npeerPrincipal := rolePrincipal(\"Org1MSP\", MSPRole_PEER) // evaluated with a client cert\n\n// after: enroll the node as a peer so its OU maps to PEER\nfabric-ca-client register --id.name peer1 --id.type peer\nfabric-ca-client enroll -u https://ca.example.com:7054 -M msp // cert now carries peer OU","handlingStrategy":"validation","validationCode":"// verify the certificate's OU maps to the required role before evaluation\ndef hasRoleOU(certPEM []byte, requiredOU string) bool {\n\tcert, _ := x509.ParseCertificate(pemToDER(certPEM))\n\tfor _, ou := range cert.Subject.OrganizationalUnit {\n\t\tif ou == requiredOU { // e.g. \"peer\", \"client\"\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","typeGuard":"func satisfiesRole(certPEM []byte, role msp.MSPRole_MSPRoleType) bool {\n\tou := map[int]string{\n\t\tint(msp.MSPRole_PEER):   \"peer\",\n\t\tint(msp.MSPRole_CLIENT): \"client\",\n\t}[int(role)]\n\treturn ou != \"\" && hasRoleOU(certPEM, ou)\n}","tryCatchPattern":"err := policy.Evaluate(id)\nif err != nil && strings.Contains(err.Error(), \"is not a [\") {\n\treturn fmt.Errorf(\"identity lacks required OU role; re-enroll with correct node type or relax the policy: %w\", err)\n}","preventionTips":["Set the correct --id.type (peer/client/admin/orderer) when registering identities in fabric-ca.","Keep NodeOUs Enable + OUIdentifiers consistent across all orgs in the channel.","Decode issued certs and verify OUs match the roles your policies demand before deployment.","Use MEMBER principals where any valid identity is acceptable instead of over-constraining to CLIENT/PEER."],"tags":["hyperledger-fabric","msp","ou-roles","policy"],"backgroundTag":"role-mismatch","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"}