apache/cassandra · error · UnauthorizedException

Only superusers are allowed to alter superuser status

Error message

Only superusers are allowed to alter superuser status

What it means

AlterRoleStatement.authorize rejects statements that set the SUPERUSER option when the authenticated user is not a superuser. Only superusers may change superuser status of any role, even one they have ALTER permission on.

Solutions

  1. Perform the ALTER as a superuser account
  2. Split the ALTER: apply non-superuser options as the current user, and ask a superuser to change SUPERUSER status
  3. Grant superuser to the operating role only if policy allows

Example fix

// before (non-super user)
ALTER ROLE app_role WITH SUPERUSER = true;
// after: run as superuser, or drop the option
ALTER ROLE app_role WITH LOGIN = true;
Defensive patterns

Strategy: validation

Validate before calling

// pre-check caller is superuser before setting SUPERUSER
if (settingSuperuser && !currentUser.isSuper())
    throw new IllegalStateException("SUPERUSER option requires a superuser account");

Try / catch

try { session.execute(alterRoleCql); } catch (UnauthorizedException e) { if (e.getMessage().contains("Only superusers are allowed to alter superuser status")) { /* rerun with superuser credentials */ } else throw e; }

Prevention

When it happens

Trigger: ALTER ROLE x WITH SUPERUSER = ... (or ALTER USER x SUPERUSER ...) executed by a non-super user, where the first self/granted-role check already passed (target role not among user's roles).

Common situations: Non-super DBA accounts attempting to promote a role; ops scripts using a service account lacking superuser; confusion between ALTER permission and superuser-only option restrictions.

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/7a52024a91e99ab1. Report an issue: GitHub.

Appendix: source

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

        // 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()))
        {
            for (Option option : opts.getOptions().keySet())
            {
                if (!DatabaseDescriptor.getRoleManager().alterableOptions().contains(option))
                    throw new UnauthorizedException(String.format("You aren't allowed to alter %s", option));

View on GitHub (pinned to 88fd0f6a0e)