alibaba/nacos · error · IllegalArgumentException
cannot delete admin: + username
Error message
cannot delete admin: + username
What it means
Thrown by UserControllerV3.deleteUser as IllegalArgumentException when the target user holds the GLOBAL_ADMIN role. The DELETE user endpoint enumerates the user's roles and refuses to remove any user whose roles include the global admin role, to prevent locking the cluster out.
Source
Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/v3/UserControllerV3.java:164
}
/**
* Delete an existed user.
*
* @param username username of user
* @return ok if deleted succeed, keep silent if user not exist
* @since 1.2.0
*/
@Since("3.0.0")
@DeleteMapping
@Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + "users",
action = ActionTypes.WRITE, apiType = ApiType.ADMIN_API)
public Result<String> deleteUser(@RequestParam String username) {
List<RoleInfo> roleInfoList = roleService.getRoles(username);
if (roleInfoList != null) {
for (RoleInfo roleInfo : roleInfoList) {
if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) {
throw new IllegalArgumentException("cannot delete admin: " + username);
}
}
}
userDetailsService.deleteUser(username);
return Result.success("delete user ok!");
}
/**
* Update an user.
*
* @param username username of user
* @param newPassword new password of user
* @param response http response
* @param request http request
* @return ok if update succeed
* @throws IllegalArgumentException if user not exist or oldPassword is incorrect
* @since 1.2.0
*/View on GitHub (pinned to 9b989acdf1)
Solutions
- First revoke or reassign the GLOBAL_ADMIN role from the user (via the role API), then delete.
- If you intend to remove the last admin, demote carefully and ensure another admin remains to avoid lockout.
- Audit roleInfoList for the user before issuing delete to fail fast in the client.
Example fix
// before
roleService.getRoles(username).forEach(r -> { /* ignore */ });
userDetailsService.deleteUser(username); // throws if admin
// after: strip admin role first
for (RoleInfo r : roleService.getRoles(username)) {
if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(r.getRole())) {
roleService.deleteRole(username, r.getRole());
}
}
userDetailsService.deleteUser(username); Defensive patterns
Strategy: validation
Validate before calling
boolean isGlobalAdmin(List<RoleInfo> roles) {
return roles != null && roles.stream()
.anyMatch(r -> AuthConstants.GLOBAL_ADMIN_ROLE.equals(r.getRole()));
}
// guard before delete: if (isGlobalAdmin(roleService.getRoles(username))) reject; Type guard
static boolean canDeleteUser(NacosRoleService rs, String username) {
List<RoleInfo> roles = rs.getRoles(username);
return roles == null || roles.stream()
.noneMatch(r -> AuthConstants.GLOBAL_ADMIN_ROLE.equals(r.getRole()));
} Try / catch
try {
userDetailsService.deleteUser(username);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("cannot delete admin")) {
// strip admin role first, then retry
} else throw e;
} Prevention
- Audit the user's roles before issuing delete.
- Strip GLOBAL_ADMIN_ROLE before deleting promoted users.
- Never let cleanup scripts delete the last admin.
When it happens
Trigger: DELETE /v3/admin/.../users?username=X where X is assigned the GLOBAL_ADMIN role. Triggered by admin-user deletion attempts via console or API.
Common situations: Attempting to delete the primary admin; deleting a user that was promoted to admin for operational reasons; cleanup scripts that do not account for admin role membership.
Related errors
- user ' + username + ' already exist!
- user + username + not exist!
- role 'ROLE_ADMIN' is not permitted to create!
- role 'ROLE_ADMIN' already exist !
- role 'ROLE_ADMIN' is not permitted to create!
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/aac02d07bffa4b89.
Report an issue: GitHub.