apache/cassandra · error · UnauthorizedException

You aren't allowed to alter

Error message

You aren't allowed to alter %s

What it means

When a role alters itself, Cassandra only allows modifying the subset of attributes declared by IRoleManager#alterableOptions(). Attempting to set a non-alterable option (e.g. SUPERUSER or PASSWORD with certain role managers) on your own role raises this UnauthorizedException.

Solutions

  1. Remove the disallowed option from the ALTER ROLE statement or apply it to another role you have ALTER permission on
  2. Have a superuser perform the change (superusers bypass the alterableOptions subset check)
  3. If using a custom IRoleManager, include the needed Option in alterableOptions()

Example fix

// before
ALTER ROLE myself WITH SUPERUSER = true;
// after
-- must be done by an existing superuser on your role
-- (as superuser):
ALTER ROLE myself WITH SUPERUSER = true;
Defensive patterns

Strategy: try-catch

Validate before calling

// only allow self-alteration of known-alterable options
java.util.Set<Option> alterable = org.apache.cassandra.config.DatabaseDescriptor.getRoleManager().alterableOptions();
if (targetRole.equals(currentUser) && !alterable.containsAll(requestedOptions)) throw new IllegalArgumentException("option not alterable on self");

Try / catch

try { session.execute(alterCql); }
catch (com.datastax.driver.core.exceptions.UnauthorizedException e) {
    if (e.getMessage().startsWith("You aren't allowed to alter")) { /* request a superuser to apply the change */ }
}

Prevention

When it happens

Trigger: Executing ALTER ROLE <own role name> WITH an option not contained in DatabaseDescriptor.getRoleManager().alterableOptions() — e.g. a role trying to make itself superuser (WITH SUPERUSER = true) or change an option the configured IRoleManager marks non-alterable.

Common situations: Users trying to self-escalate to superuser; using a custom IRoleManager implementation whose alterableOptions() set is narrower than expected; confusing self-alteration rules with altering other roles (which requires ALTER permission instead).

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

            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));
            }
        }
        else
        {
            // if not attempting to alter another role, ensure we have ALTER permissions on it
            super.checkPermission(state, Permission.ALTER, role);
        }
    }

    public ResultMessage execute(ClientState state) throws RequestValidationException, RequestExecutionException
    {
        if (ifExists && !DatabaseDescriptor.getRoleManager().isExistingRole(role))
            return null;

        if (opts.isGeneratedPassword())
        {
            String generatedPassword = Guardrails.passwordPolicy.generate(state, Map.of());
            if (generatedPassword != null)

View on GitHub (pinned to 88fd0f6a0e)