{"record":{"id":"aac02d07bffa4b89","repo":"alibaba/nacos","slug":"cannot-delete-admin-username","errorCode":null,"errorMessage":"cannot delete admin:  + username","messagePattern":"cannot delete admin:  \\+ username","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/v3/UserControllerV3.java","lineNumber":164,"sourceCode":"    }\n    \n    /**\n     * Delete an existed user.\n     *\n     * @param username username of user\n     * @return ok if deleted succeed, keep silent if user not exist\n     * @since 1.2.0\n     */\n    @Since(\"3.0.0\")\n    @DeleteMapping\n    @Secured(resource = AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX + \"users\",\n        action = ActionTypes.WRITE, apiType = ApiType.ADMIN_API)\n    public Result<String> deleteUser(@RequestParam String username) {\n        List<RoleInfo> roleInfoList = roleService.getRoles(username);\n        if (roleInfoList != null) {\n            for (RoleInfo roleInfo : roleInfoList) {\n                if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) {\n                    throw new IllegalArgumentException(\"cannot delete admin: \" + username);\n                }\n            }\n        }\n        userDetailsService.deleteUser(username);\n        return Result.success(\"delete user ok!\");\n    }\n    \n    /**\n     * Update an user.\n     *\n     * @param username    username of user\n     * @param newPassword new password of user\n     * @param response    http response\n     * @param request     http request\n     * @return ok if update succeed\n     * @throws IllegalArgumentException if user not exist or oldPassword is incorrect\n     * @since 1.2.0\n     */","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/v3/UserControllerV3.java#L146-L182","documentation":"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.","triggerScenarios":"DELETE /v3/admin/.../users?username=X where X is assigned the GLOBAL_ADMIN role. Triggered by admin-user deletion attempts via console or API.","commonSituations":"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.","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."],"exampleFix":"// before\nroleService.getRoles(username).forEach(r -> { /* ignore */ });\nuserDetailsService.deleteUser(username); // throws if admin\n\n// after: strip admin role first\nfor (RoleInfo r : roleService.getRoles(username)) {\n    if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(r.getRole())) {\n        roleService.deleteRole(username, r.getRole());\n    }\n}\nuserDetailsService.deleteUser(username);","handlingStrategy":"validation","validationCode":"boolean isGlobalAdmin(List<RoleInfo> roles) {\n    return roles != null && roles.stream()\n        .anyMatch(r -> AuthConstants.GLOBAL_ADMIN_ROLE.equals(r.getRole()));\n}\n// guard before delete: if (isGlobalAdmin(roleService.getRoles(username))) reject;","typeGuard":"static boolean canDeleteUser(NacosRoleService rs, String username) {\n    List<RoleInfo> roles = rs.getRoles(username);\n    return roles == null || roles.stream()\n        .noneMatch(r -> AuthConstants.GLOBAL_ADMIN_ROLE.equals(r.getRole()));\n}","tryCatchPattern":"try {\n    userDetailsService.deleteUser(username);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"cannot delete admin\")) {\n        // strip admin role first, then retry\n    } else throw e;\n}","preventionTips":["Audit the user's roles before issuing delete.","Strip GLOBAL_ADMIN_ROLE before deleting promoted users.","Never let cleanup scripts delete the last admin."],"tags":["auth","user","admin","delete","illegal-argument"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}