{"record":{"id":"ee8f2926cc2f5fc6","repo":"apache/cassandra","slug":"s-schema-is-protected","errorCode":null,"errorMessage":"%s schema is protected","messagePattern":"(.+?) schema is protected","errorType":"exception","errorClass":"UnauthorizedException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/ClientState.java","lineNumber":505,"sourceCode":"    {\n        validateKeyspace(keyspace);\n\n        if (isInternal)\n            return;\n\n        validateLogin();\n\n        preventSystemKSSchemaModification(keyspace, resource, perm);\n\n        // Some system data is always readable\n        if ((perm == Permission.SELECT) && READABLE_SYSTEM_RESOURCES.contains(resource))\n            return;\n\n        // Modifications to any resource upon which the authenticator, authorizer or role manager depend should not be\n        // be performed by users\n        if (PROTECTED_AUTH_RESOURCES.contains(resource))\n            if ((perm == Permission.CREATE) || (perm == Permission.ALTER) || (perm == Permission.DROP))\n                throw new UnauthorizedException(String.format(\"%s schema is protected\", resource));\n\n        ensurePermission(perm, resource);\n    }\n\n    public void ensurePermission(Permission perm, IResource resource)\n    {\n        if (!DatabaseDescriptor.getAuthorizer().requireAuthorization())\n            return;\n\n        // Access to built in functions is unrestricted\n        if(resource instanceof FunctionResource && resource.hasParent())\n            if (((FunctionResource)resource).getKeyspace().equals(SchemaConstants.SYSTEM_KEYSPACE_NAME))\n                return;\n\n        if (resource instanceof DataResource && isOrdinaryUser())\n        {\n            DataResource dataResource = (DataResource)resource;\n            if (!dataResource.isRootLevel())","sourceCodeStart":487,"sourceCodeEnd":523,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/ClientState.java#L487-L523","documentation":"ClientState.ensurePermission (the resource-aware overload) refuses CREATE/ALTER/DROP on any resource in PROTECTED_AUTH_RESOURCES — the keyspaces/tables backing the authenticator, authorizer, and role manager (system_auth and configured auth keyspaces). It throws UnauthorizedException stating the schema is protected, so users cannot break the auth subsystem that governs their own access.","triggerScenarios":"Executing `ALTER KEYSPACE system_auth ...`, `DROP TABLE system_auth.roles`, `CREATE TABLE system_auth.x`, or similar DDL via a client session whose permission check hits this guard.","commonSituations":"Operators trying to change the replication factor of system_auth with a normal user account (a common RF-fix recipe) and getting blocked; tooling attempting schema cleanup inside auth keyspaces; custom IAuthenticator/IAuthorizer configured keyspaces also fall under the guard.","solutions":["Perform auth-keyspace changes with internal state (or as a node-local operation), e.g. run the replication change through the auth configuration mechanism rather than client DDL.","If RF change is needed, use the supported path: update cassandra.yaml auth keyspace settings and apply via tooling that operates outside user permission checks, then `nodetool repair`.","Log in with the intended non-protected workflow: Cassandra superusers are still subject to this protection — modify via JMX/nodetool or offline tools instead.","For custom auth, relocate auth data to a dedicated keyspace and manage it outside client sessions."],"exampleFix":"// before\nALTER KEYSPACE system_auth WITH replication = {'class':'NetworkTopologyStrategy','dc1':3};\n-- UnauthorizedException: system_auth schema is protected\n// after\n# run node-locally / via supported tooling, then:\nnodetool repair -pr system_auth","handlingStrategy":"try-catch","validationCode":"boolean protectedRes = resource.toString().startsWith(\"<keyspace system_auth>\");\nif (protectedRes && (perm == CREATE || perm == ALTER || perm == DROP))\n    throw new IllegalArgumentException(\"Use node-local tooling to modify auth keyspaces\");","typeGuard":null,"tryCatchPattern":"try { session.execute(ddl); } catch (UnauthorizedException e) {\n    if (e.getMessage().endsWith(\"schema is protected\")) logger.error(\"Auth schema is guarded; use supported tooling instead\");\n}","preventionTips":["Never issue DDL against system_auth (or configured auth keyspaces) from client sessions","Change auth keyspace replication only through supported, node-local procedures","Document that even superusers hit this guard","Keep custom authenticator/authorizer keyspaces outside routine client workflows"],"tags":["cassandra","authorization","system-auth","ddl"],"backgroundTag":"permission-denied","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"}