apache/cassandra · error · AuthenticationException
%s is not permitted to log in
Error message
%s is not permitted to log in
What it means
ClientState.login() accepts an AuthenticatedUser only if the user is anonymous or canLogin() succeeds (the role exists and is not disabled); otherwise it throws AuthenticationException stating the user is not permitted to log in. This covers roles that were deleted or had LOGIN disabled after a client obtained credentials.
Source
Thrown at src/java/org/apache/cassandra/service/ClientState.java:417
// Skip keyspace validation for non-authenticated users. Apparently, some client libraries
// call set_keyspace() before calling login(), and we have to handle that.
if (user != null && Schema.instance.getKeyspaceMetadata(ks) == null)
throw new InvalidRequestException("Keyspace '" + ks + "' does not exist");
keyspace = ks;
}
/**
* Attempts to login the given user.
*/
public void login(AuthenticatedUser user)
{
if (user.isAnonymous() || canLogin(user))
{
this.user = user;
this.superuserStatus = null;
}
else
throw new AuthenticationException(String.format("%s is not permitted to log in", user.getName()));
}
private boolean canLogin(AuthenticatedUser user)
{
try
{
return user.canLogin();
}
catch (RequestExecutionException | RequestValidationException e)
{
throw new AuthenticationException("Unable to perform authentication: " + e.getMessage(), e);
}
}
public void ensureAllKeyspacesPermission(Permission perm)
{
if (isInternal)
return;View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Re-enable the role: `ALTER ROLE <name> WITH LOGIN = true`.
- Recreate the missing role: `CREATE ROLE <name> WITH PASSWORD = ... AND LOGIN = true`.
- Check CIDR group restrictions (cidr_groups / authorizer settings) that may block the role's login.
- Verify the authenticator's stored credentials exist in system_auth (repair system_auth if replication was broken).
Example fix
// before cqlsh -u appsvc -p secret # AuthenticationException: appsvc is not permitted to log in // after (as superuser) ALTER ROLE appsvc WITH LOGIN = true;
Defensive patterns
Strategy: try-catch
Validate before calling
// as superuser, before deploying credentials:
Row r = session.execute("SELECT can_login FROM system_auth.roles WHERE role = ?", role).one();
boolean canLogin = r != null && r.getBool("can_login"); Try / catch
try { client.connect(user, pass); } catch (AuthenticationException e) {
if (e.getMessage().contains("not permitted to log in")) alert("Role disabled or missing: " + user);
} Prevention
- Run `LIST ROLES` to confirm role exists and has LOGIN before distributing credentials
- Avoid disabling LOGIN on roles still used by services
- When integrating external auth, ensure the mapped role exists in Cassandra
- Keep system_auth replicated correctly so role lookups succeed
When it happens
Trigger: Authenticating credentials whose role row is missing from system_auth.roles, or whose can_login flag is false; calling login(user) for a role that was disabled via `ALTER ROLE x WITH LOGIN = false`.
Common situations: User logged in after an operator ran `ALTER ROLE app WITH LOGIN = false`; role dropped while the client still uses its credentials; LDAP/external auth mapping to a role that doesn't exist in Cassandra; cidr/IP restrictions rejecting the login (canLogin false).
Related errors
- Cannot DROP primary role for current login
- %s doesn't support %s
- Invalid value for property '%s'. It must be a boolean
- Invalid value for property '%s'. It must be a string
- Properties '%s' and '%s' are mutually exclusive
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/0a8708718fbfb186.
Report an issue: GitHub.