{"record":{"id":"e367d0325bb70760","repo":"alibaba/nacos","slug":"username-nacos-anonymous-is-reserved-by-the","errorCode":null,"errorMessage":"username '__nacos_anonymous__' is reserved by the system","messagePattern":"username '__nacos_anonymous__' is reserved by the system","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/users/AbstractCachedUserService.java","lineNumber":70,"sourceCode":"            \n            Map<String, User> map = new ConcurrentHashMap<>(16);\n            for (User user : users.getPageItems()) {\n                map.put(user.getUsername(), user);\n            }\n            userMap = map;\n        } catch (Exception e) {\n            Loggers.AUTH.warn(\"[LOAD-USERS] load failed\", e);\n        }\n    }\n    \n    /**\n     * Reject reserved system usernames from being created or deleted.\n     *\n     * @param username the username to check\n     */\n    protected void rejectReservedUsername(String username) {\n        if (AuthConstants.ANONYMOUS_USER.equals(username)) {\n            throw new IllegalArgumentException(\n                \"username '\" + AuthConstants.ANONYMOUS_USER + \"' is reserved by the system\");\n        }\n    }\n    \n    /**\n     * [ISSUE #13625] check username and password is blank.\n     */\n    protected void validateUserCredentials(String username, String password) {\n        if (StringUtils.isBlank(username)) {\n            throw new IllegalArgumentException(\"username is blank\");\n        }\n        rejectReservedUsername(username);\n        if (StringUtils.isBlank(password)) {\n            throw new IllegalArgumentException(\"password is blank\");\n        }\n    }\n}\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/users/AbstractCachedUserService.java#L52-L88","documentation":"The username __nacos_anonymous__ is the internal sentinel for unauthenticated/anonymous principals; letting it be created or deleted would let someone impersonate the anonymous identity or break anonymous-access semantics. rejectReservedUsername() throws IllegalArgumentException whenever a user-management operation targets that exact name.","triggerScenarios":"Calling createUser('__nacos_anonymous__', password) or deleteUser('__nacos_anonymous__') via the user API, or any path that routes through validateUserCredentials/rejectReservedUsername with that username.","commonSituations":"Automated provisioning scripts iterating a name list that accidentally includes the reserved name; security testing/fuzzing of usernames; a UI that lets the user type any string.","solutions":["Skip or rename the reserved username in your provisioning input.","Add a client-side guard that blocks the literal '__nacos_anonymous__' before calling the API.","Audit role/permission scripts for the same sentinel name."],"exampleFix":"// before\nuserService.createUser(\"__nacos_anonymous__\", pwd, true); // IllegalArgumentException\n\n// after\nprivate static final Set<String> RESERVED = Set.of(\"__nacos_anonymous__\", \"nacos\");\nif (RESERVED.contains(username)) {\n    throw new IllegalArgumentException(\"username is reserved: \" + username);\n}\nuserService.createUser(username, pwd, true);","handlingStrategy":"validation","validationCode":"// Block reserved usernames before any user-management call.\nimport com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants;\nimport com.alibaba.nacos.common.utils.StringUtils;\n\nif (StringUtils.isBlank(username)\n        || AuthConstants.ANONYMOUS_USER.equals(username)) {\n    throw new IllegalArgumentException(\"username is blank or reserved: \" + username);\n}","typeGuard":null,"tryCatchPattern":"try {\n    userService.createUser(username, password, false);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"reserved\")) {\n        return Result.failure(400, e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Maintain a client-side blocklist of reserved names (__nacos_anonymous__, nacos).","Validate input before calling the API.","Return a clear 400 instead of letting the plugin throw.","Audit provisioning scripts for reserved names."],"tags":["auth","user-management","validation","reserved-name"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}