apache/cassandra · error · IllegalArgumentException
Cannot instantiate a non-virtual table
Error message
Cannot instantiate a non-virtual table
What it means
AbstractVirtualTable's constructor validates that the TableMetadata passed in is flagged virtual. Constructing a virtual-table instance for a regular (disk-backed) table metadata would break the contract that virtual tables are purely in-memory, so IllegalArgumentException is thrown at construction time. This is a developer-facing invariant check, not a runtime query error.
Source
Thrown at src/java/org/apache/cassandra/db/virtual/AbstractVirtualTable.java:55
import org.apache.cassandra.db.partitions.UnfilteredPartitionIterator;
import org.apache.cassandra.db.rows.UnfilteredRowIterator;
import org.apache.cassandra.dht.AbstractBounds;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.schema.TableMetadata;
import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis;
/**
* An abstract virtual table implementation that builds the resultset on demand.
*/
public abstract class AbstractVirtualTable implements VirtualTable
{
protected final TableMetadata metadata;
protected AbstractVirtualTable(TableMetadata metadata)
{
if (!metadata.isVirtual())
throw new IllegalArgumentException("Cannot instantiate a non-virtual table");
this.metadata = metadata;
}
public TableMetadata metadata()
{
return metadata;
}
/**
* Provide a {@link DataSet} that is contains all of the virtual table's data.
*/
public abstract DataSet data();
/**
* Provide a {@link DataSet} that is potentially restricted to the provided partition - but is allowed to contain
* other partitions.
*/View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Add .virtual() to the TableMetadata builder before constructing the table
- Verify the table is registered in a VirtualKeyspace, not a regular Schema keyspace
- Double-check the factory (AbstractVirtualTable.Factory) receives metadata created for the virtual schema
Example fix
// before
TableMetadata metadata = TableMetadata.builder("my_vks", "my_table")
.addPartitionKeyColumn("k", UTF8Type.instance)
.build(); // not virtual
// after
TableMetadata metadata = TableMetadata.builder("my_vks", "my_table")
.virtual()
.addPartitionKeyColumn("k", UTF8Type.instance)
.build(); Defensive patterns
Strategy: validation
Validate before calling
if (!metadata.isVirtual()) throw new IllegalArgumentException("must pass virtual TableMetadata to virtual table constructor"); Type guard
boolean isVirtualMeta = m -> m.isVirtual();
Try / catch
try { new MyVirtualTable(metadata); } catch (IllegalArgumentException e) { rebuildMetadataAsVirtual(); } Prevention
- Always call .virtual() on the TableMetadata builder for virtual tables
- Register virtual tables only in VirtualKeyspace instances
- Add a unit test constructing each virtual table at startup
When it happens
Trigger: Registering a VirtualTable implementation with TableMetadata built without .virtual() (e.g. forgetting TableMetadata.builder(...).virtual() or adding the table to the wrong registry — VirtualKeyspace vs regular keyspace).
Common situations: Developing a custom virtual table and forgetting the .virtual() flag on the builder; wiring an existing table's metadata into VirtualTable.initialize; copy-paste of a regular table definition into a virtual keyspace.
Related errors
- Unknown keyspace/cf pair (%s.%s)
- Keyspace " + keyspaceName + " does not exist
- Field '%s' doesn't exist in type '%s.%s'
- Unknown keyspace: '" + keyspaceName + "'
- Unknown object type: '" + objectType + "'. Valid types are:
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/3d2c03adece08f9a.
Report an issue: GitHub.