apache/cassandra · error · UnauthorizedException

Cannot

Error message

Cannot %s %s

What it means

Thrown as UnauthorizedException when a DDL operation other than a permitted keyspace-level ALTER targets a replicated system keyspace (system_auth, system_distributed, system_traces). Only ALTER of replication parameters at the keyspace level is allowed; all other operations (CREATE, DROP, table-level changes) are rejected with a 'Cannot <perm> <resource>' message.

Solutions

  1. If changing replication factors of system_auth/system_distributed/system_traces, use ALTER KEYSPACE <ks> WITH replication = {...} while holding ALTER permission on that keyspace resource.
  2. Do not DROP or CREATE replicated system keyspaces; they are required by Cassandra internals.
  3. Check the permission and resource level: the allowance only applies when perm == ALTER and resource.isKeyspaceLevel().
  4. Grant the required permission: GRANT ALTER ON KEYSPACE system_auth TO role.

Example fix

// before
DROP KEYSPACE system_traces;
// after
ALTER KEYSPACE system_traces WITH replication = {'class':'NetworkTopologyStrategy','dc1':3};
Defensive patterns

Strategy: validation

Validate before calling

import static org.apache.cassandra.db.SchemaConstants.isReplicatedSystemKeyspace;
if (isReplicatedSystemKeyspace(keyspace) && !(isKeyspaceLevelAlter))
    throw new IllegalStateException("Only keyspace-level ALTER is allowed on " + keyspace);

Prevention

When it happens

Trigger: Executing CREATE/DROP on a replicated system keyspace, ALTER TABLE on a table inside one (non-keyspace-level resource), or ALTER KEYSPACE without the ALTER permission / at table level, e.g. DROP KEYSPACE system_traces, ALTER TABLE system_auth.roles WITH ... .

Common situations: Operators trying to drop system_traces or system_distributed to 'clean up'; attempting to recreate system_auth after auth misconfiguration; adjusting replication of system keyspaces via table-level ALTER; automated tooling applying uniform DDL to every keyspace.

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

Appendix: source

Thrown at src/java/org/apache/cassandra/service/ClientState.java:596

    private void preventSystemKSSchemaModification(String keyspace, DataResource resource, Permission perm)
    {
        // we only care about DDL statements
        if (perm != Permission.ALTER && perm != Permission.DROP && perm != Permission.CREATE)
            return;

        // prevent ALL local system keyspace modification
        if (SchemaConstants.isLocalSystemKeyspace(keyspace))
            throw new UnauthorizedException(keyspace + " keyspace is not user-modifiable.");

        if (SchemaConstants.isReplicatedSystemKeyspace(keyspace))
        {
            // allow users with sufficient privileges to alter replication params of replicated system keyspaces
            if (perm == Permission.ALTER && resource.isKeyspaceLevel())
                return;

            // prevent all other modifications of replicated system keyspaces
            throw new UnauthorizedException(String.format("Cannot %s %s", perm, resource));
        }
    }

    public void validateLogin()
    {
        if (user == null)
        {
            throw new UnauthorizedException("You have not logged in");
        }
        else if (!user.hasLocalAccess())
        {
            throw new UnauthorizedException(String.format("You do not have access to this datacenter (%s)", Datacenters.thisDatacenter()));
        }
        else
        {
            if (remoteAddress != null && !user.hasAccessFromIp(remoteAddress))
                throw new UnauthorizedException("You do not have access from this IP " + remoteAddress.getHostString());
        }

View on GitHub (pinned to 88fd0f6a0e)