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

  1. Re-enable the role: `ALTER ROLE <name> WITH LOGIN = true`.
  2. Recreate the missing role: `CREATE ROLE <name> WITH PASSWORD = ... AND LOGIN = true`.
  3. Check CIDR group restrictions (cidr_groups / authorizer settings) that may block the role's login.
  4. 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

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


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