alibaba/nacos · warning · IllegalArgumentException
role 'ROLE_ADMIN' is not permitted to create!
Error message
role 'ROLE_ADMIN' is not permitted to create!
What it means
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.
Source
Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceRemoteImpl.java:170
return result.getData();
} catch (NacosException e) {
throw new NacosRuntimeException(e.getErrCode(), e.getErrMsg());
} catch (Exception unpectedException) {
throw new NacosRuntimeException(NacosException.SERVER_ERROR,
unpectedException.getMessage());
}
}
@Override
public List<RoleInfo> getAllRoles() {
return getRoles(StringUtils.EMPTY, StringUtils.EMPTY, DEFAULT_PAGE_NO, Integer.MAX_VALUE)
.getPageItems();
}
@Override
public void addRole(String role, String username) {
if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(role)) {
throw new IllegalArgumentException(
"role '" + AuthConstants.GLOBAL_ADMIN_ROLE + "' is not permitted to create!");
}
if (AuthConstants.ANONYMOUS_ROLE.equals(role)) {
throw new IllegalArgumentException(
"role '" + AuthConstants.ANONYMOUS_ROLE + "' is reserved by the system");
}
Map<String, String> body = Map.of("role", role, "username", username);
try {
HttpRestResult<String> httpResult = nacosRestTemplate.postForm(
buildRemoteRoleUrlPath(AuthConstants.ROLE_PATH),
RemoteServerUtil.buildServerRemoteHeader(), body, String.class);
RemoteServerUtil.singleCheckResult(httpResult);
getCachedRoleSet().add(role);
invalidateUserRoles(username);
} catch (NacosException e) {
throw new NacosRuntimeException(e.getErrCode(), e.getErrMsg());
} catch (Exception unpectedException) {
throw new NacosRuntimeException(NacosException.SERVER_ERROR,View on GitHub (pinned to 9b989acdf1)
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.
Example fix
// before
roleService.addRole("ROLE_ADMIN", username); // rejected locally
// after
roleService.addAdminRole(username); Defensive patterns
Strategy: validation
Validate before calling
if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(role)) {
roleService.addAdminRole(username);
} else {
roleService.addRole(role, username);
} Prevention
- Route admin grants through addAdminRole, never addRole.
- Filter ROLE_ADMIN from role-provisioning lists.
- Treat reserved role names as non-creatable in automation.
When it happens
Trigger: Console-side addRole("ROLE_ADMIN", username); seeding roles from a catalog that includes the admin role via the remote impl.
Common situations: Console deployment forwarding auth ops attempting to create the admin role through the wrong endpoint; automation that does not filter reserved names.
Related errors
- role 'ROLE_ADMIN' is not permitted to create!
- role '__nacos_anonymous_role__' is reserved by the system
- role '__nacos_anonymous_role__' is reserved by the system
- role 'ROLE_ADMIN' already exist !
- cannot delete admin: + username
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/95b9d19b06c91e30.
Report an issue: GitHub.