alibaba/nacos · error · IllegalArgumentException

role '__nacos_anonymous_role__' is reserved by the system

Error message

role '__nacos_anonymous_role__' is reserved by the system

What it means

Thrown by AbstractCheckedRoleService.rejectReservedRole when an attempt is made to delete or manually create the anonymous role (__nacos_anonymous_role__). This role is reserved by the system for unauthenticated access and cannot be removed or recreated through the API. The guard prevents breaking anonymous/public access functionality.

Source

Thrown at plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/AbstractCheckedRoleService.java:152

    /**
     * Mark the local global-admin lookup cache after an administrator role is created.
     */
    protected void markGlobalAdminRolePresent() {
        hasGlobalAdminRole = true;
    }
    
    /**
     * Reject deletion or manual creation of system-reserved roles.
     *
     * @param role role name to check
     */
    protected void rejectReservedRole(String role) {
        if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(role)) {
            throw new IllegalArgumentException(
                "role '" + AuthConstants.GLOBAL_ADMIN_ROLE + "' is not permitted to delete!");
        }
        if (AuthConstants.ANONYMOUS_ROLE.equals(role)) {
            throw new IllegalArgumentException(
                "role '" + AuthConstants.ANONYMOUS_ROLE + "' is reserved by the system");
        }
    }
    
    /**
     * If API is update user password, don't do permission check, because there is permission check in API logic.
     */
    private boolean isUpdatePasswordPermission(Permission permission) {
        Properties properties = permission.getResource().getProperties();
        return null != properties && properties.contains(AuthConstants.UPDATE_PASSWORD_ENTRY_POINT);
    }
    
    private String joinResource(Resource resource) {
        if (SignType.SPECIFIED.equals(resource.getType())) {
            return resource.getName();
        }
        StringBuilder result = new StringBuilder();
        String namespaceId = resource.getNamespaceId();

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Do not attempt to delete __nacos_anonymous_role__ — it is required for anonymous/public API access.
  2. Filter system-reserved roles (ROLE_ADMIN, __nacos_anonymous_role__) out of any batch role operations.
  3. If you want to disable anonymous access, configure nacos.core.auth.enabled=true and manage permissions instead of removing the role.
  4. In role management tooling, maintain a deny-list of reserved role names.

Example fix

// before
for (String role : allRoles) {
    roleService.deleteRole(role); // throws on __nacos_anonymous_role__
}

// after
Set<String> reserved = Set.of(AuthConstants.GLOBAL_ADMIN_ROLE, AuthConstants.ANONYMOUS_ROLE);
for (String role : allRoles) {
    if (!reserved.contains(role)) {
        roleService.deleteRole(role);
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// Check for reserved role before attempting deletion
Set<String> reservedRoles = Set.of(
    AuthConstants.GLOBAL_ADMIN_ROLE,
    AuthConstants.ANONYMOUS_ROLE
);
if (reservedRoles.contains(roleName)) {
    throw new IllegalArgumentException("Cannot delete system-reserved role: " + roleName);
}
roleService.deleteRole(roleName);

Type guard

public static boolean isReservedRole(String role) {
    return AuthConstants.GLOBAL_ADMIN_ROLE.equals(role)
        || AuthConstants.ANONYMOUS_ROLE.equals(role);
}

Try / catch

try {
    roleService.deleteRole(roleName);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("reserved by the system")) {
        return Result.failed("Role '" + roleName + "' is reserved and cannot be deleted");
    }
    throw e;
}

Prevention

When it happens

Trigger: An admin API call attempts to delete or create a role named __nacos_anonymous_role__. The rejectReservedRole method catches this and throws before any persistence operation. This can happen via direct API calls, automated scripts, or tools that enumerate and delete all roles.

Common situations: Cleanup or migration script deletes all roles indiscriminately; a security audit tool attempts to remove the anonymous role; an admin tries to restructure roles and remove the default anonymous role; test setup code wipes all roles between tests.

Related errors


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