apache/cassandra · error · UnauthorizedException

You aren't allowed to alter your own superuser status or…

Error message

You aren't allowed to alter your own superuser status or that of a role granted to you

What it means

AlterRoleStatement.authorize rejects attempts by a user to change the SUPERUSER option of their own role, or of any role granted to them (directly or transitively via user.getRoles()). This closes a privilege-escalation path where a user could grant or revoke their own superuser status.

Solutions

  1. Have a different (superuser) account that is not a grantee of the target role perform the ALTER
  2. ALTER the role under a different name/admin role not granted to you
  3. If self-modification is genuinely required, revoke the role grant from the operating user first (as another superuser)

Example fix

// before (as user granted 'admin')
ALTER ROLE admin WITH SUPERUSER = true;
// after (from an unrelated superuser account)
ALTER ROLE admin WITH SUPERUSER = true;
Defensive patterns

Strategy: validation

Validate before calling

// pre-check: target role must not be one of the caller's roles when changing SUPERUSER
List<Role> myRoles = getGrantedRoles(currentUser);
if (settingSuperuser && myRoles.stream().anyMatch(r -> r.name.equals(targetRole)))
    throw new IllegalStateException("Cannot alter SUPERUSER status of own/granted role " + targetRole);

Try / catch

try { session.execute(alterRoleCql); } catch (UnauthorizedException e) { if (e.getMessage().contains("alter your own superuser status")) { /* use another superuser account */ } else throw e; }

Prevention

When it happens

Trigger: ALTER ROLE myrole WITH SUPERUSER = true/false where the authenticated user's role set (user.getRoles()) contains the target role, regardless of whether the user is a superuser.

Common situations: Self-service scripts where admins alter their own account; a superuser who is also a member of the target role; automation credentials that share roles with the account being modified.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/c52ec601940389ba. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/AlterRoleStatement.java:103

            // Ensure input CIDR group names are valid, i.e, existing in CIDR groups mapping table
            cidrPermissions.validate();
        }

        // validate login here before authorize, to avoid leaking user existence to anonymous users.
        state.ensureNotAnonymous();
        if (!DatabaseDescriptor.getRoleManager().isExistingRole(role))
        {
            checkTrue(ifExists, "Role %s doesn't exist", role.getRoleName());
        }
    }

    public void authorize(ClientState state) throws UnauthorizedException
    {
        AuthenticatedUser user = state.getUser();
        boolean isSuper = user.isSuper();

        if (opts.getSuperuser().isPresent() && user.getRoles().contains(role))
            throw new UnauthorizedException("You aren't allowed to alter your own superuser " +
                                            "status or that of a role granted to you");

        if (opts.getSuperuser().isPresent() && !isSuper)
            throw new UnauthorizedException("Only superusers are allowed to alter superuser status");

        if (dcPermissions != null && !isSuper)
            throw new UnauthorizedException("Only superusers are allowed to alter access to datacenters.");

        if (cidrPermissions != null && !isSuper)
            throw new UnauthorizedException("Only superusers are allowed to alter access from CIDR groups.");

        // superusers can do whatever else they like
        if (isSuper)
            return;

        // a role may only modify the subset of its own attributes as determined by IRoleManager#alterableOptions
        if (user.getName().equals(role.getRoleName()))
        {

View on GitHub (pinned to 88fd0f6a0e)