{"record":{"id":"216a05a01db2f784","repo":"apache/cassandra","slug":"system-keyspace-s-is-not-user-modifiable","errorCode":null,"errorMessage":"System keyspace '%s' is not user-modifiable","messagePattern":"System keyspace '(.+?)' is not user-modifiable","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/AlterSchemaStatement.java","lineNumber":174,"sourceCode":"    {\n        return ImmutableSet.of();\n    }\n\n    /**\n     * Schema alteration might produce a client warning (e.g. a warning to run full repair when increading RF of a keyspace).\n     * This method should be used to generate them instead of calling warn() in transformation code.\n     *\n     * Only called if the transformation resulted in a non-empty diff.\n     */\n    Set<String> clientWarnings(KeyspacesDiff diff)\n    {\n        return ImmutableSet.of();\n    }\n\n    public ResultMessage execute(QueryState state)\n    {\n        if (SchemaConstants.isLocalSystemKeyspace(keyspaceName))\n            throw ire(\"System keyspace '%s' is not user-modifiable\", keyspaceName);\n\n        KeyspaceMetadata keyspace = Schema.instance.getKeyspaceMetadata(keyspaceName);\n        if (null != keyspace && keyspace.isVirtual())\n            throw ire(\"Virtual keyspace '%s' is not user-modifiable\", keyspaceName);\n\n        validateKeyspaceName(keyspaceName, AlterSchemaStatement::ire);\n\n        setExecutionTimestamp(state.getTimestamp());\n        // Perform a 'dry-run' attempt to apply the transformation locally before submitting to the CMS. This can save a\n        // round trip to the CMS for things syntax errors, but also fail fast for things like configuration errors.\n        // Such failures may be dependent on the specific node's config (for things like guardrails/memtable\n        // config/etc), but executing a schema change which has already been committed by the CMS should always succeed\n        // or else the node cannot make progress on any subsequent metadata changes. For this reason, validation errors\n        // during execution are trapped and the node will fall back to safe default config wherever possible. Attempting\n        // to apply the SchemaTransformation at this point will catch any such error which occurs locally before\n        // submission to the CMS, but it can't guarantee that the statement can be applied as-is on every node in the\n        // cluster, as config can be heterogenous falling back to safe defaults may occur on some nodes.\n        ClusterMetadata metadata = ClusterMetadata.current();","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/AlterSchemaStatement.java#L156-L192","documentation":"This InvalidRequestException is thrown when a CQL schema-altering statement (CREATE/ALTER/DROP KEYSPACE or TABLE) targets a local system keyspace such as 'system', 'system_schema', etc. Local system keyspaces are managed internally by Cassandra and must never be modified through user-issued DDL, so AlterSchemaStatement.execute rejects them before any schema transformation is attempted.","triggerScenarios":"Executing any AlterSchemaStatement subclass (e.g. ALTER KEYSPACE, CREATE TABLE, DROP TABLE) whose keyspaceName resolves via SchemaConstants.isLocalSystemKeyspace, e.g. 'ALTER KEYSPACE system WITH ...' or 'CREATE TABLE system_schema.foo (...)'","commonSituations":"Running migration or provisioning scripts that mistakenly point DDL at 'system'/'system_schema'; tools that auto-generate DDL against a connection whose default keyspace is a system keyspace; typos like 'system_schemA' vs a real user keyspace.","solutions":["Target a user-created keyspace instead of a system/local keyspace","If replicating system keyspace settings is intended, change cluster-level configuration or auth setup rather than issuing DDL","Check USE <keyspace> statements in the session; switch USE to a user keyspace before running DDL"],"exampleFix":"// before\nsession.execute(\"ALTER TABLE system.size_estimates WITH gc_grace_seconds = 0\");\n// after\n// system keyspaces are not user-modifiable; use a user keyspace\nsession.execute(\"ALTER TABLE my_app.metrics WITH gc_grace_seconds = 0\");","handlingStrategy":"validation","validationCode":"Set<String> systemKeyspaces = Set.of(\"system\",\"system_schema\",\"system_auth\",\"system_distributed\",\"system_traces\",\"system_views\",\"system_virtual_schema\");\nif (systemKeyspaces.contains(keyspace.toLowerCase()))\n    throw new IllegalArgumentException(\"Refusing DDL on system keyspace: \" + keyspace);","typeGuard":"boolean isUserKeyspace(String ks) {\n    return ks != null && !SchemaConstants.isLocalSystemKeyspace(ks);\n}","tryCatchPattern":"try {\n    session.execute(ddl);\n} catch (InvalidRequestException e) {\n    if (e.getMessage().contains(\"is not user-modifiable\"))\n        log.warn(\"DDL skipped: {} targets a protected keyspace\", ddl);\n    else throw e;\n}","preventionTips":["Never USE a system keyspace in application sessions","Whitelist target keyspaces in migration tooling","Filter system/virtual keyspaces when enumerating keyspaces for DDL"],"tags":["cassandra","cql","ddl","schema"],"backgroundTag":"invalid-argument-value","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}