apache/cassandra · error · RuntimeException

Invalid metadata has been detected for role %s

Error message

Invalid metadata has been detected for role %s

What it means

CassandraRoleManager wraps the NullPointerException thrown when a role row's is_superuser or can_login boolean fails to deserialize into a RuntimeException 'Invalid metadata has been detected for role %s'. It indicates corrupted or invalidly-written data in the system_auth.roles table.

Source

Thrown at src/java/org/apache/cassandra/auth/CassandraRoleManager.java:151

    // Transform a row in the AuthKeyspace.ROLES to a Role instance
    private static final Function<UntypedResultSet.Row, Role> ROW_TO_ROLE = row ->
    {
        try
        {
            return new Role(row.getString("role"),
                            row.getBoolean("is_superuser"),
                            row.getBoolean("can_login"),
                            Collections.emptyMap(),
                            row.has("member_of") ? row.getSet("member_of", UTF8Type.instance)
                                                 : Collections.<String>emptySet());
        }
        // Failing to deserialize a boolean in is_superuser or can_login will throw an NPE
        catch (NullPointerException e)
        {
            logger.warn("An invalid value has been detected in the {} table for role {}. If you are " +
                        "unable to login, you may need to disable authentication and confirm " +
                        "that values in that table are accurate", AuthKeyspace.ROLES, row.getString("role"));
            throw new RuntimeException(String.format("Invalid metadata has been detected for role %s", row.getString("role")), e);
        }
    };

    private static int PASSWORD_UPDATE_MIN_INTERVAL_MS = CassandraRelevantProperties.ROLE_PASSWORD_UPDATE_MIN_INTERVAL_MS.getInt();
    // in-memory protection against excessive loadRoleWithWritetimeStatement queries
    private static Cache<String, Boolean> recentPasswordUpdates = Caffeine.newBuilder()
                                        .expireAfterWrite(PASSWORD_UPDATE_MIN_INTERVAL_MS, TimeUnit.MILLISECONDS)
                                        .build();

    @VisibleForTesting
    public static synchronized void updatePasswordUpdateMinInterval(int newInterval)
    {
        recentPasswordUpdates = Caffeine.newBuilder().expireAfterWrite(newInterval, TimeUnit.MILLISECONDS).build();
        PASSWORD_UPDATE_MIN_INTERVAL_MS = newInterval;
    }

    private SelectStatement loadRoleStatement;
    private SelectStatement loadIdentityStatement;

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Enable the described mitigation: temporarily set authenticator to AllowAllAuthenticator so you can log in.
  2. Inspect the row: SELECT role, can_login, is_superuser FROM system_auth.roles WHERE role = '<role>';
  3. Repair the row with correct boolean values: UPDATE system_auth.roles SET can_login = true, is_superuser = false WHERE role = '<role>';
  4. If system_auth is broadly corrupt, restore it from a consistent backup or recreate roles.

Example fix

// cqlsh repair of the corrupted role row
UPDATE system_auth.roles SET can_login = true, is_superuser = false WHERE role = 'bob';
Defensive patterns

Strategy: validation

Validate before calling

-- detect corrupt role rows before they break login
SELECT role, can_login, is_superuser FROM system_auth.roles;
-- any NULL in can_login/is_superuser is a problem row

Try / catch

try {
    roleManager.getRole(roleName);
} catch (RuntimeException e) {
    if (e.getMessage().startsWith("Invalid metadata has been detected")) {
        repairRoleRow(roleName); // UPDATE can_login/is_superuser
    }
}

Prevention

When it happens

Trigger: loadRole from system_auth.roles where the is_superuser or can_login column value cannot be deserialized as a boolean (null/garbage bytes in the cell).

Common situations: Manual edits to system_auth, partial or failed upgrades/migrations, restoring auth tables from inconsistent snapshots, or rows written by a different schema version.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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