{"record":{"id":"8d72f8271a59f6d4","repo":"apache/cassandra","slug":"failed-to-disconnect-invalid-roles","errorCode":null,"errorMessage":"Failed to disconnect invalid roles","messagePattern":"Failed to disconnect invalid roles","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/auth/CassandraRoleManager.java","lineNumber":805,"sourceCode":"            return entries;\n        };\n    }\n\n    protected void disconnectInvalidRoles()\n    {\n        // This should always run with jitter, otherwise there's a risk that all nodes disconnect clients at the same time\n        StorageService.instance.disconnectInvalidRoles();\n    }\n\n    protected void invalidRoleDisconnectTask(LongSupplier delayMillis, ScheduledExecutorService executor)\n    {\n        try\n        {\n            disconnectInvalidRoles();\n        }\n        catch (Exception e)\n        {\n            logger.warn(\"Failed to disconnect invalid roles\", e);\n        }\n\n        long nextDelayMillis = delayMillis.getAsLong();\n        logger.info(\"Scheduling next invalid role disconnection in {} millis\", nextDelayMillis);\n        this.invalidRoleDisconnectTask = executor.schedule(() -> invalidRoleDisconnectTask(delayMillis, executor), nextDelayMillis, TimeUnit.MILLISECONDS);\n    }\n\n    protected void scheduleDisconnectInvalidRoleTask()\n    {\n        // Cancel any pending execution if it exists, since we may have changed period / jitter parameters\n        if (this.invalidRoleDisconnectTask != null)\n        {\n            logger.debug(\"Canceling previous invalidRoleDisconnectTask\");\n            this.invalidRoleDisconnectTask.cancel(true);\n        }\n\n        long period = getInvalidClientDisconnectPeriodMillis();\n        long jitter = getInvalidClientDisconnectMaxJitterMillis();","sourceCodeStart":787,"sourceCodeEnd":823,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/auth/CassandraRoleManager.java#L787-L823","documentation":"CassandraRoleManager's periodic invalidRoleDisconnectTask logs 'Failed to disconnect invalid roles' at WARN when disconnecting sessions of roles whose metadata failed validation throws. The task is non-fatal: it reschedules itself after nextDelayMillis.","triggerScenarios":"Background task disconnectInvalidRoles() throws while iterating active client sessions whose authenticated role has invalid metadata (e.g. rows like error 2774) — failures in the session/connection registry or auth lookup.","commonSituations":"Clusters with corrupted system_auth role rows where enforcement of invalid-role disconnection repeatedly fails; concurrent client churn causing race conditions while iterating sessions.","solutions":["Check the attached stack trace to see why disconnection failed (usually a secondary exception, not the role metadata itself).","Fix the underlying invalid role rows (see error 2774 solutions) so fewer sessions need forced disconnection.","Verify ClientState/connection registry health; restart the node if session tracking is wedged.","The task auto-retries — after fixing root cause, confirm the warning stops appearing in logs."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"-- find and fix invalid role rows so disconnection succeeds\nSELECT role, can_login, is_superuser FROM system_auth.roles WHERE can_login = null ALLOW FILTERING;","typeGuard":null,"tryCatchPattern":"try {\n    disconnectInvalidRoles();\n} catch (Exception e) {\n    logger.warn(\"Failed to disconnect invalid roles\", e); // inspect cause, task reschedules anyway\n}","preventionTips":["Fix invalid role rows promptly — they also degrade the disconnection task.","Watch logs for repeated warnings; persistent failure points to session-registry issues.","Restart the node if the invalid-role task appears wedged."],"tags":["auth","roles","background-task","sessions"],"backgroundTag":"database-query-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}