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

  1. First revoke or reassign the GLOBAL_ADMIN role from the user (via the role API), then delete.
  2. If you intend to remove the last admin, demote carefully and ensure another admin remains to avoid lockout.
  3. 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

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


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/aac02d07bffa4b89. Report an issue: GitHub.