apache/cassandra · error · UnauthorizedException
Only superusers can bind identities to a role with…
Error message
Only superusers can bind identities to a role with superuser status
What it means
An authorization check in AddIdentityStatement.authorize: a non-superuser attempting to CREATE an identity bound to a role that currently has superuser status is rejected with UnauthorizedException. This prevents privilege escalation by letting ordinary users attach credentials/identities to superuser roles.
Solutions
- Run the statement as a superuser
- Remove superuser status from the target role first (as a superuser), then add the identity
- Pick a different, non-superuser role to bind the identity to
Example fix
// before (as non-super user) CREATE IDENTITY cert1 FOR 'superadmin'; // after: run as superuser, or CREATE IDENTITY cert1 FOR 'app_role'; -- non-superuser role
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check before issuing CREATE IDENTITY
boolean targetIsSuper = roleManager.isSuper(RoleResource.role(roleName));
boolean iAmSuper = clientUser.isSuper();
if (targetIsSuper && !iAmSuper) throw new IllegalStateException("Need superuser to bind identity to superuser role " + roleName); Try / catch
try { session.execute(createIdentity); } catch (UnauthorizedException e) { if (e.getMessage().contains("Only superusers can bind identities")) { /* escalate credentials or target non-super role */ } else throw e; } Prevention
- Run identity-provisioning scripts with superuser credentials
- List role superuser status (LIST ROLES) before binding identities
- Never point identity automation at the default superuser role
When it happens
Trigger: CREATE IDENTITY ... FOR role 'x' (or equivalent AddIdentityStatement execution) where the authenticated user is not a superuser and DatabaseDescriptor.getRoleManager().isSuper(RoleResource.role(role)) returns true for the target role.
Common situations: Admin delegation setups where a lesser admin manages identities but tries to add one for the built-in superuser or another superuser role; scripts running under non-super credentials that previously worked against non-super roles.
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
- Only superusers are allowed to alter superuser status
- Can not add identity for non-existent role
- Failed to disconnect invalid roles
- Invalid metadata has been detected for role
- Invalid value for property
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/59c1a6b9d35559d2.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/AddIdentityStatement.java:58
{
final String identity;
final String role;
final boolean ifNotExists;
public AddIdentityStatement(String identity, String role, boolean ifNotExists)
{
this.role = role;
this.identity = identity;
this.ifNotExists = ifNotExists;
}
@Override
public void authorize(ClientState state)
{
checkPermission(state, Permission.CREATE, RoleResource.root());
if (!state.getUser().isSuper() && DatabaseDescriptor.getRoleManager().isSuper(RoleResource.role(role)))
throw new UnauthorizedException("Only superusers can bind identities to a role with superuser status");
}
@Override
public void validate(ClientState state)
{
state.ensureNotAnonymous();
if (!DatabaseDescriptor.getRoleManager().isExistingRole(RoleResource.role(role)))
{
throw new InvalidRequestException(String.format("Can not add identity for non-existent role '%s'", role));
}
if (!ifNotExists && DatabaseDescriptor.getRoleManager().isExistingIdentity(identity))
throw new InvalidRequestException(String.format("%s already exists", identity));
}
@Override
public AuditLogContext getAuditLogContext()View on GitHub (pinned to 88fd0f6a0e)