{"record":{"id":"7ea60619144c43ee","repo":"hyperledger/fabric","slug":"this-identity-is-not-an-admin","errorCode":null,"errorMessage":"This identity is not an admin","messagePattern":"This identity is not an admin","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"msp/mspimpl.go","lineNumber":518,"sourceCode":"\t\tif mspRole.MspIdentifier != msp.name {\n\t\t\treturn errors.Errorf(\"the identity is a member of a different MSP (expected %s, got %s)\", mspRole.MspIdentifier, id.GetMSPIdentifier())\n\t\t}\n\n\t\t// now we validate the different msp roles\n\t\tswitch mspRole.Role {\n\t\tcase m.MSPRole_MEMBER:\n\t\t\t// in the case of member, we simply check\n\t\t\t// whether this identity is valid for the MSP\n\t\t\tmspLogger.Debugf(\"Checking if identity satisfies MEMBER role for %s\", msp.name)\n\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","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/msp/mspimpl.go#L500-L536","documentation":"Raised when a MSPPrincipal_ROLE principal with Role=ADMIN is evaluated: the identity passes the MSP-ID check but is not found in the MSP's admin certificate list (isInAdmins fails). Only identities whose certificate exactly matches one of the configured admin certs satisfy an ADMIN principal.","triggerScenarios":"A policy requires an ADMIN principal (e.g. lifecycle/chaincode or channel-admin policies, _lifecycle commit checks) and the supplied identity is a member/client/peer of the MSP but not one of the admins listed in the MSP configuration (fabricCA admin cert in configtx / admincerts folder).","commonSituations":"MSP config deployed without admincerts (common with newer fabric-ca setups that rely on OUs, while the policy still demands ADMIN); identity enrolled with a non-admin role; admin cert rotated/expired in channel config; peer MSP directory missing the admincerts file.","solutions":["Use the actual admin identity (one whose cert appears in the MSP's admincerts) to sign the operation.","Add or update the admin certificate in the organization definition (configtx yaml / peer msp admincerts) and update channel config.","If using OU-based roles, ensure the MSP config has OUIdentifiers set and FabricNodeOUs enabled, and the policy matches an OU the identity actually has.","Re-enroll the identity from fabric-ca with the admin affiliation/type so its certificate is issued as an admin."],"exampleFix":"// before: signing with a regular client identity\nctx, err := gateway.Evaluate(...) // identity: client cert -> 'This identity is not an admin'\n\n// after: use the org admin identity from the wallet\nadminIdentity, _ := wallet.Get(\"orgAdmin\")\nctx, err := gateway.Evaluate(...) // identity: admin cert present in MSP admincerts","handlingStrategy":"validation","validationCode":"// check the cert is listed among the MSP admin certs before attempting admin ops\ndef isAdmin(certPEM []byte, adminCerts [][]byte) bool {\n\tparsed, _ := x509.ParseCertificate(pemToDER(certPEM))\n\tfor _, a := range adminCerts {\n\t\tap, _ := x509.ParseCertificate(pemToDER(a))\n\t\tif parsed.Equal(ap) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","typeGuard":"func hasAdminCert(id fabric.Identity, adminCerts [][]byte) bool {\n\tcertPEM, _ := id.Certificate()\n\treturn isAdmin(certPEM, adminCerts)\n}","tryCatchPattern":"err := adminOp(ctx)\nif err != nil && strings.Contains(err.Error(), \"not an admin\") {\n\tlog.Fatalf(\"identity is not in MSP admincerts; use the org admin identity or update channel config\")\n}","preventionTips":["Ensure admincerts are included in the org MSP config (configtx or peer msp directory).","Track admin cert expiry and rotate before expiration via config update.","Keep the org admin identity in a separate, protected wallet.","If relying on OUs for admin role, enable FabricNodeOUs and set admin OUIdentifiers consistently."],"tags":["hyperledger-fabric","msp","admin","policy"],"backgroundTag":"insufficient-permissions","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"}