{"record":{"id":"8dec22602f33745a","repo":"alibaba/nacos","slug":"role-role-admin-already-exist","errorCode":null,"errorMessage":"role 'ROLE_ADMIN' already exist !","messagePattern":"role 'ROLE_ADMIN' already exist !","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceDirectImpl.java","lineNumber":155,"sourceCode":"        }\n        \n        if (isUserBoundToRole(role, username)) {\n            throw new IllegalArgumentException(\n                \"user '\" + username + \"' already bound to the role '\" + role + \"'!\");\n        }\n        \n        rolePersistService.addRole(role, username);\n        getCachedRoleSet().add(role);\n        invalidateUserRoles(username);\n    }\n    \n    @Override\n    public void addAdminRole(String username) {\n        if (userDetailsService.getUser(username) == null) {\n            throw new IllegalArgumentException(\"user '\" + username + \"' not found!\");\n        }\n        if (hasGlobalAdminRole()) {\n            throw new IllegalArgumentException(\n                \"role '\" + AuthConstants.GLOBAL_ADMIN_ROLE + \"' already exist !\");\n        }\n        \n        rolePersistService.addRole(AuthConstants.GLOBAL_ADMIN_ROLE, username);\n        getCachedRoleSet().add(AuthConstants.GLOBAL_ADMIN_ROLE);\n        markGlobalAdminRolePresent();\n    }\n    \n    @Override\n    public void deleteRole(String role, String userName) {\n        rejectReservedRole(role);\n        rolePersistService.deleteRole(role, userName);\n        invalidateUserRoles(userName);\n    }\n    \n    @Override\n    public void deleteRole(String role) {\n        rejectReservedRole(role);","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceDirectImpl.java#L137-L173","documentation":"Thrown by addAdminRole(username) when hasGlobalAdminRole() is already true, meaning the ROLE_ADMIN global administrator role already exists in the system. Nacos tracks admin-role presence and refuses to create a second admin binding through this path, enforcing a single-admin invariant. It is an IllegalArgumentException surfaced as a validation error.","triggerScenarios":"Calling addAdminRole when an admin already exists (e.g. during re-bootstrap against a non-empty database); promoting a second user to admin while one is already configured; rerunning setup scripts against existing state.","commonSituations":"Re-running an init/bootstrap job against a DB that already has an admin; forgetting the cluster was already initialized; Helm/k8s redeploy that re-attempts admin seeding.","solutions":["Check roleService.hasGlobalAdminRole() (or query existing admin) before calling addAdminRole.","Make admin bootstrap idempotent: skip promotion when an admin already exists.","If you truly need to change the admin user, use the standard user/role admin APIs rather than re-running addAdminRole."],"exampleFix":"// before\nroleService.addAdminRole(username); // throws: admin already exists\n\n// after\nif (!roleService.hasGlobalAdminRole()) {\n    roleService.addAdminRole(username);\n}","handlingStrategy":"validation","validationCode":"if (roleService.hasGlobalAdminRole()) {\n    // admin already configured; skip bootstrap promotion\n    return;\n}\nroleService.addAdminRole(username);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make admin bootstrap idempotent by checking hasGlobalAdminRole first.","Avoid re-running init scripts against an already-initialized DB.","Track initialization state externally so setup does not re-seed the admin."],"tags":["auth","role","admin","duplicate","bootstrap"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}