alibaba/nacos · warning · IllegalArgumentException
role 'ROLE_ADMIN' already exist !
Error message
role 'ROLE_ADMIN' already exist !
What it means
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.
Source
Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceDirectImpl.java:155
}
if (isUserBoundToRole(role, username)) {
throw new IllegalArgumentException(
"user '" + username + "' already bound to the role '" + role + "'!");
}
rolePersistService.addRole(role, username);
getCachedRoleSet().add(role);
invalidateUserRoles(username);
}
@Override
public void addAdminRole(String username) {
if (userDetailsService.getUser(username) == null) {
throw new IllegalArgumentException("user '" + username + "' not found!");
}
if (hasGlobalAdminRole()) {
throw new IllegalArgumentException(
"role '" + AuthConstants.GLOBAL_ADMIN_ROLE + "' already exist !");
}
rolePersistService.addRole(AuthConstants.GLOBAL_ADMIN_ROLE, username);
getCachedRoleSet().add(AuthConstants.GLOBAL_ADMIN_ROLE);
markGlobalAdminRolePresent();
}
@Override
public void deleteRole(String role, String userName) {
rejectReservedRole(role);
rolePersistService.deleteRole(role, userName);
invalidateUserRoles(userName);
}
@Override
public void deleteRole(String role) {
rejectReservedRole(role);View on GitHub (pinned to 9b989acdf1)
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.
Example fix
// before
roleService.addAdminRole(username); // throws: admin already exists
// after
if (!roleService.hasGlobalAdminRole()) {
roleService.addAdminRole(username);
} Defensive patterns
Strategy: validation
Validate before calling
if (roleService.hasGlobalAdminRole()) {
// admin already configured; skip bootstrap promotion
return;
}
roleService.addAdminRole(username); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- role 'ROLE_ADMIN' is not permitted to create!
- user '{username}' already bound to the role '{role}'!
- role 'ROLE_ADMIN' is not permitted to create!
- 50001
- 50001
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/8dec22602f33745a.
Report an issue: GitHub.