{"record":{"id":"8f521265bda31cb1","repo":"apache/cassandra","slug":"virtual-keyspace-s-is-not-user-modifiable","errorCode":null,"errorMessage":"Virtual keyspace '%s' is not user-modifiable","messagePattern":"Virtual 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":178,"sourceCode":"    /**\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();\n        Keyspaces proposed = apply(metadata);\n        KeyspacesDiff localDiff =  Keyspaces.diff(metadata.schema.getKeyspaces(), proposed);\n        if (localDiff.isEmpty())\n            return new ResultMessage.Void();","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/AlterSchemaStatement.java#L160-L196","documentation":"This InvalidRequestException is thrown when a schema-altering statement targets a virtual keyspace (e.g. 'system_views', 'system_virtual_schema'). Virtual keyspaces are in-memory views over runtime state with no underlying SSTables, so DDL against them is meaningless and rejected in AlterSchemaStatement.execute.","triggerScenarios":"Executing any AlterSchemaStatement subclass where Schema.instance.getKeyspaceMetadata(keyspaceName) returns non-null and KeyspaceMetadata.isVirtual() is true, e.g. 'ALTER KEYSPACE system_views WITH replication = ...'","commonSituations":"Monitoring/ops scripts attempting to configure or index virtual tables; accidental tab-completion into system_views when writing DDL; tooling that iterates all keyspaces and applies DDL to each.","solutions":["Do not issue DDL against virtual keyspaces; they are read-only projections of node state","If you need different runtime settings, configure the underlying real keyspace or node configuration instead","Filter virtual keyspaces out of automation loops (skip keyspaceMetadata.isVirtual())"],"exampleFix":"// before\nsession.execute(\"ALTER TABLE system_views.current_sessions WITH crc_check_chance = 0\");\n// after\n// virtual tables are read-only; remove DDL against system_views","handlingStrategy":"validation","validationCode":"KeyspaceMetadata ks = Schema.instance.getKeyspaceMetadata(keyspaceName);\nif (ks != null && ks.isVirtual())\n    throw new IllegalArgumentException(\"Refusing DDL on virtual keyspace: \" + keyspaceName);","typeGuard":"boolean isVirtualKeyspace(String ks) {\n    KeyspaceMetadata m = Schema.instance.getKeyspaceMetadata(ks);\n    return m != null && m.isVirtual();\n}","tryCatchPattern":"try {\n    session.execute(ddl);\n} catch (InvalidRequestException e) {\n    if (e.getMessage().startsWith(\"Virtual keyspace\"))\n        log.warn(\"Skipped read-only virtual keyspace DDL: {}\", ddl);\n    else throw e;\n}","preventionTips":["Treat system_views/system_virtual_schema as read-only monitoring surfaces","Skip virtual keyspaces in schema-automation loops","Consult system_schema.keyspaces to distinguish virtual keyspaces before DDL"],"tags":["cassandra","cql","ddl","virtual-keyspace"],"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-17T15:17:12.973Z"}