{"record":{"id":"95b9d19b06c91e30","repo":"alibaba/nacos","slug":"role-role-admin-is-not-permitted-to-create-95b9d1","errorCode":null,"errorMessage":"role 'ROLE_ADMIN' is not permitted to create!","messagePattern":"role 'ROLE_ADMIN' is not permitted to create!","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/roles/NacosRoleServiceRemoteImpl.java","lineNumber":170,"sourceCode":"            return result.getData();\n        } catch (NacosException e) {\n            throw new NacosRuntimeException(e.getErrCode(), e.getErrMsg());\n        } catch (Exception unpectedException) {\n            throw new NacosRuntimeException(NacosException.SERVER_ERROR,\n                unpectedException.getMessage());\n        }\n    }\n    \n    @Override\n    public List<RoleInfo> getAllRoles() {\n        return getRoles(StringUtils.EMPTY, StringUtils.EMPTY, DEFAULT_PAGE_NO, Integer.MAX_VALUE)\n            .getPageItems();\n    }\n    \n    @Override\n    public void addRole(String role, String username) {\n        if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(role)) {\n            throw new IllegalArgumentException(\n                \"role '\" + AuthConstants.GLOBAL_ADMIN_ROLE + \"' is not permitted to create!\");\n        }\n        if (AuthConstants.ANONYMOUS_ROLE.equals(role)) {\n            throw new IllegalArgumentException(\n                \"role '\" + AuthConstants.ANONYMOUS_ROLE + \"' is reserved by the system\");\n        }\n        Map<String, String> body = Map.of(\"role\", role, \"username\", username);\n        try {\n            HttpRestResult<String> httpResult = nacosRestTemplate.postForm(\n                buildRemoteRoleUrlPath(AuthConstants.ROLE_PATH),\n                RemoteServerUtil.buildServerRemoteHeader(), body, String.class);\n            RemoteServerUtil.singleCheckResult(httpResult);\n            getCachedRoleSet().add(role);\n            invalidateUserRoles(username);\n        } catch (NacosException e) {\n            throw new NacosRuntimeException(e.getErrCode(), e.getErrMsg());\n        } catch (Exception unpectedException) {\n            throw new NacosRuntimeException(NacosException.SERVER_ERROR,","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceRemoteImpl.java#L152-L188","documentation":"Thrown by NacosRoleServiceRemoteImpl.addRole (the remote/console path) when the role name equals GLOBAL_ADMIN_ROLE (\"ROLE_ADMIN\"). Identical guard to the direct impl: the admin role must be granted via addAdminRole, never via the generic role-add. The check is local to the console node before it even forwards the request, so no remote call is made.","triggerScenarios":"Console-side addRole(\"ROLE_ADMIN\", username); seeding roles from a catalog that includes the admin role via the remote impl.","commonSituations":"Console deployment forwarding auth ops attempting to create the admin role through the wrong endpoint; automation that does not filter reserved names.","solutions":["Use roleService.addAdminRole(username) to grant admin privileges.","Filter ROLE_ADMIN out of any role list passed to addRole.","Treat reserved role names as non-creatable in your provisioning logic."],"exampleFix":"// before\nroleService.addRole(\"ROLE_ADMIN\", username); // rejected locally\n\n// after\nroleService.addAdminRole(username);","handlingStrategy":"validation","validationCode":"if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(role)) {\n    roleService.addAdminRole(username);\n} else {\n    roleService.addRole(role, username);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Route admin grants through addAdminRole, never addRole.","Filter ROLE_ADMIN from role-provisioning lists.","Treat reserved role names as non-creatable in automation."],"tags":["auth","role","reserved","admin","remote"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}