apache/cassandra · error · InvalidRequestException
Cannot include a virtual table statement in a logged batch
Error message
Cannot include a virtual table statement in a logged batch
What it means
Virtual tables (system_virtual_schema-backed, e.g. system_views) are read-only in-memory views and cannot be part of a logged batch. validate() rejects logged batches containing any mutation directed at a virtual table.
Source
Thrown at src/java/org/apache/cassandra/cql3/statements/BatchStatement.java:303
hasVirtualTables = true;
else
hasRegularTables = true;
}
if (timestampSet && hasCounters)
throw new InvalidRequestException("Cannot provide custom timestamp for a BATCH containing counters");
if (isCounter() && hasNonCounters)
throw new InvalidRequestException("Cannot include non-counter statement in a counter batch");
if (hasCounters && hasNonCounters)
throw new InvalidRequestException("Counter and non-counter mutations cannot exist in the same batch");
if (isLogged() && hasCounters)
throw new InvalidRequestException("Cannot include a counter statement in a logged batch");
if (isLogged() && hasVirtualTables)
throw new InvalidRequestException("Cannot include a virtual table statement in a logged batch");
if (hasVirtualTables && hasRegularTables)
throw new InvalidRequestException("Mutations for virtual and regular tables cannot exist in the same batch");
if (hasConditions && hasVirtualTables)
throw new InvalidRequestException("Conditional BATCH statements cannot include mutations for virtual tables");
if (hasConditions)
{
String ksName = null;
String cfName = null;
for (ModificationStatement stmt : statements)
{
if (ksName != null && (!stmt.keyspace().equals(ksName) || !stmt.table().equals(cfName)))
throw new InvalidRequestException("Batch with conditions cannot span multiple tables: " + stmt.source);
ksName = stmt.keyspace();
cfName = stmt.table();
}View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Remove the virtual table mutation from the batch — virtual tables do not accept writes at all
- If a virtual-table-like write was intended, verify the keyspace/table name; you likely meant a regular table
- Use the underlying regular table or the correct operational mechanism instead of mutating virtual tables
Example fix
// before
BEGIN BATCH UPDATE system_views.settings SET value = 'x' WHERE key = 'k'; APPLY BATCH;
// after
-- remove the statement; virtual tables are read-only
INSERT INTO my_settings (key, value) VALUES ('k', 'x'); Defensive patterns
Strategy: validation
Validate before calling
if (statements.stream().anyMatch(s -> isVirtualTable(s.getTable())) && batchType == BatchType.LOGGED)
throw new IllegalArgumentException("Virtual tables are read-only; remove from batch"); Type guard
boolean isVirtualTable(TableMetadata tm) { return tm.isVirtual(); } Try / catch
catch (InvalidRequestException e) { if (e.getMessage().contains("virtual table")) { sanitizeTableListAndRetry(); } else throw e; } Prevention
- Exclude system_views/system virtual keyspaces from any write-generating code
- Check TableMetadata.isVirtual() before building any write against discovered tables
- Never template batches over 'all tables' lists without filtering
When it happens
Trigger: 'BEGIN BATCH UPDATE system_views.some_virtual_table ...; APPLY BATCH' — attempting any mutation on a virtual table within a logged batch.
Common situations: Automation scripts or monitoring tools trying to 'reset' virtual table data; copy-pasted batch templates applied against virtual tables.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot include a counter statement in a logged batch
- Mutations for virtual and regular tables cannot exist in the
- Conditional BATCH statements cannot include mutations for vi
- Global TTL on the BATCH statement is not supported.
- Cannot provide custom timestamp for conditional BATCH
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/491945e268702db5.
Report an issue: GitHub.