apache/cassandra · error · InvalidRequestException
Virtual keyspace ' ' is not user-modifiable
Error message
Virtual keyspace '%s' is not user-modifiable
What it means
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.
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())
Example fix
// before
session.execute("ALTER TABLE system_views.current_sessions WITH crc_check_chance = 0");
// after
// virtual tables are read-only; remove DDL against system_views Defensive patterns
Strategy: validation
Validate before calling
KeyspaceMetadata ks = Schema.instance.getKeyspaceMetadata(keyspaceName);
if (ks != null && ks.isVirtual())
throw new IllegalArgumentException("Refusing DDL on virtual keyspace: " + keyspaceName); Type guard
boolean isVirtualKeyspace(String ks) {
KeyspaceMetadata m = Schema.instance.getKeyspaceMetadata(ks);
return m != null && m.isVirtual();
} Try / catch
try {
session.execute(ddl);
} catch (InvalidRequestException e) {
if (e.getMessage().startsWith("Virtual keyspace"))
log.warn("Skipped read-only virtual keyspace DDL: {}", ddl);
else throw e;
} Prevention
- 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
When it happens
Trigger: 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 = ...'
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- ACCESS TO DATACENTERS operations not supported by…
- Altering column types is no longer supported
- Cannot add a counter column to Accord table
- Cannot add new column to a COMPACT STORAGE table
- Cannot drop a table when materialized views still depend on…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/8f521265bda31cb1.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/AlterSchemaStatement.java:178
/**
* Schema alteration might produce a client warning (e.g. a warning to run full repair when increading RF of a keyspace).
* This method should be used to generate them instead of calling warn() in transformation code.
*
* Only called if the transformation resulted in a non-empty diff.
*/
Set<String> clientWarnings(KeyspacesDiff diff)
{
return ImmutableSet.of();
}
public ResultMessage execute(QueryState state)
{
if (SchemaConstants.isLocalSystemKeyspace(keyspaceName))
throw ire("System keyspace '%s' is not user-modifiable", keyspaceName);
KeyspaceMetadata keyspace = Schema.instance.getKeyspaceMetadata(keyspaceName);
if (null != keyspace && keyspace.isVirtual())
throw ire("Virtual keyspace '%s' is not user-modifiable", keyspaceName);
validateKeyspaceName(keyspaceName, AlterSchemaStatement::ire);
setExecutionTimestamp(state.getTimestamp());
// Perform a 'dry-run' attempt to apply the transformation locally before submitting to the CMS. This can save a
// round trip to the CMS for things syntax errors, but also fail fast for things like configuration errors.
// Such failures may be dependent on the specific node's config (for things like guardrails/memtable
// config/etc), but executing a schema change which has already been committed by the CMS should always succeed
// or else the node cannot make progress on any subsequent metadata changes. For this reason, validation errors
// during execution are trapped and the node will fall back to safe default config wherever possible. Attempting
// to apply the SchemaTransformation at this point will catch any such error which occurs locally before
// submission to the CMS, but it can't guarantee that the statement can be applied as-is on every node in the
// cluster, as config can be heterogenous falling back to safe defaults may occur on some nodes.
ClusterMetadata metadata = ClusterMetadata.current();
Keyspaces proposed = apply(metadata);
KeyspacesDiff localDiff = Keyspaces.diff(metadata.schema.getKeyspaces(), proposed);
if (localDiff.isEmpty())
return new ResultMessage.Void();View on GitHub (pinned to 88fd0f6a0e)