{"record":{"id":"ddcb1240ac411e99","repo":"hyperledger/fabric","slug":"the-identity-is-not-an-admin-under-this-msp-s","errorCode":null,"errorMessage":"The identity is not an admin under this MSP [%s]","messagePattern":"The identity is not an admin under this MSP \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"msp/mspimpl.go","lineNumber":658,"sourceCode":"\n\t\t// now we validate the admin role only, the other roles are left to the v1.3 function\n\t\tswitch mspRole.Role {\n\t\tcase m.MSPRole_ADMIN:\n\t\t\tmspLogger.Debugf(\"Checking if identity has been named explicitly as an admin 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\n\t\t\t// or it carries the Admin OU, in this case check that the identity is valid as well.\n\t\t\tmspLogger.Debugf(\"Checking if identity carries the admin ou for %s\", 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, m.MSPRole_ADMIN); err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"The identity is not an admin under this MSP [%s]\", msp.name)\n\t\t\t}\n\n\t\t\treturn nil\n\t\tcase m.MSPRole_ORDERER:\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\t}\n\t}\n\n\t// Use the v1.3 function to check other principal types\n\treturn msp.satisfiesPrincipalInternalV13(id, principal)","sourceCodeStart":640,"sourceCodeEnd":676,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/msp/mspimpl.go#L640-L676","documentation":"In the MSPRole_ADMIN branch, after the identity passes msp.Validate, the code checks whether the identity actually carries the ADMIN OU via msp.hasOURole(id, MSPRole_ADMIN). If it does not, this error is wrapped and returned: the identity is valid under the MSP but is not an admin by OU. This only happens when the identity was not explicitly named in the MSP's admin certificate list and OU enforcement is enabled.","triggerScenarios":"Calling SatisfiesPrincipal (or evaluating an endorsement/policy chain) with an ADMIN principal where the identity: (a) is not listed among the MSP's adminCerts, (b) has OU enforcement enabled, and (c) lacks the ADMIN OU (per config.yaml ouIdentifier/adminsOUIdentifier) in its certificate.","commonSituations":"Expecting a peer or client certificate to grant admin rights when admins cert list wasn't updated during org setup; OU identifier in config.yaml mismatching the OU embedded in the admin cert; using an org member (CLIENT/PEER OU) cert where an admin cert is required; configtx.yaml admin role setup not reflected in the deployed local MSP.","solutions":["Add the identity's signing certificate to the MSP's admins list (channel config Admins policy / local MSP admincerts) or re-generate the MSP config including it as admin","Ensure the cert's OU matches the adminsOUIdentifier configured in the MSP's config.yaml when OU enforcement is on","Re-enroll/re-issue the admin certificate with the correct OU from the org CA","Confirm the peer/client actually loaded the updated admincerts (restart peer after replacing local MSP files)"],"exampleFix":"// before — MEMBER role cert used for ADMIN principal\nrole := &m.MSPRole{MspIdentifier: \"Org1MSP\", Role: m.MSPRole_MEMBER}\n// after — enroll an ADMIN-OU cert or name the cert in admincerts\nrole := &m.MSPRole{MspIdentifier: \"Org1MSP\", Role: m.MSPRole_ADMIN}\n// plus: put admin cert in msp/admincerts/ and update the channel org's Admins policy","handlingStrategy":"validation","validationCode":"// confirm the cert is either in admincerts or carries the ADMIN OU before evaluating\nif _, err := os.Stat(filepath.Join(mspDir, \"admincerts\", certFile)); err != nil {\n\t// not a listed admin; verify OU\n\tblock, _ := pem.Decode(certPEM)\n\tcert, _ := x509.ParseCertificate(block.Bytes)\n\tvar hasAdminOU bool\n\tfor _, ou := range cert.Subject.OrganizationalUnit { if ou == \"admin\" { hasAdminOU = true } }\n\tif !hasAdminOU { return errors.New(\"identity is not an admin of this MSP\") }\n}","typeGuard":null,"tryCatchPattern":"if err := msp.SatisfiesPrincipal(id, adminPrincipal); err != nil {\n\tif strings.Contains(err.Error(), \"not an admin under this MSP\") {\n\t\treturn fmt.Errorf(\"identity lacks ADMIN privileges; add cert to admincerts or enroll with admin OU: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Explicitly list admin certificates in the org's local MSP admincerts and channel Admins policy","When using node OUs, enroll admin identities with an 'admin' OU and set adminsOUIdentifier in config.yaml","Re-deploy/restart nodes after replacing MSP admincerts so changes take effect","Separate admin credentials from member credentials and verify which is loaded before admin operations"],"tags":["fabric","msp","admin-role","ou-enforcement","authorization"],"backgroundTag":"identity-not-admin","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"}