apache/cassandra · error · InvalidRequestException

Row deletion is not supported by table

Error message

Row deletion is not supported by table %s

What it means

The default applyRowDeletion implementation of AbstractMutableLazyVirtualTable throws this error: deleting individual rows is not supported unless the concrete virtual table overrides it. Virtual tables must explicitly enable row deletes.

Solutions

  1. Check the documentation of the specific virtual table to see which mutations it supports.
  2. If the table does not support deletion, address the underlying runtime state that produces the rows.
  3. If you implement the virtual table, override applyRowDeletion to implement the delete.
Defensive patterns

Strategy: try-catch

Try / catch

try {
    session.execute("DELETE FROM system_views.some_table WHERE pk = ? AND ck = ?", pk, ck);
} catch (InvalidQueryException e) {
    if (e.getMessage().contains("Row deletion is not supported")) {
        // table is not row-deletable; use the appropriate administrative interface
    }
}

Prevention

When it happens

Trigger: Executing 'DELETE FROM <virtual_table> WHERE <partition key> [AND <clustering key>]' against a virtual table that has not overridden applyRowDeletion(Object[], Object[]).

Common situations: Users assuming all mutable-looking virtual tables accept DELETE of rows; automation scripts deleting stale entries from virtual tables like batchlog-like or metrics views.

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/7acd41d39eab70fa. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/db/virtual/AbstractMutableLazyVirtualTable.java:70

    protected AbstractMutableLazyVirtualTable(TableMetadata metadata, OnTimeout onTimeout, Sorted sorted, Sorted sortedByPartitionKey)
    {
        super(metadata, onTimeout, sorted, sortedByPartitionKey);
    }

    protected void applyPartitionDeletion(Object[] partitionKeys)
    {
        throw invalidRequest("Partition deletion is not supported by table %s", metadata());
    }

    protected void applyRangeTombstone(Object[] partitionKey, Object[] start, boolean startInclusive, Object[] end, boolean endInclusive)
    {
        throw invalidRequest("Range deletion is not supported by table %s", metadata());
    }

    protected void applyRowDeletion(Object[] partitionKey, @Nullable Object[] clusteringKeys)
    {
        throw invalidRequest("Row deletion is not supported by table %s", metadata());
    }

    protected void applyRowUpdate(Object[] partitionKeys, @Nullable Object[] clusteringKeys, ColumnMetadata[] columns, Object[] values)
    {
        throw invalidRequest("Column modification is not supported by table %s", metadata());
    }

    private void applyRangeTombstone(Object[] pks, RangeTombstone rt)
    {
        Slice slice = rt.deletedSlice();
        Object[] starts = composeClusterings(slice.start(), metadata());
        Object[] ends = composeClusterings(slice.end(), metadata());
        applyRangeTombstone(pks, starts, slice.start().isInclusive(), ends, slice.end().isInclusive());
    }

    private void applyRow(Object[] pks, Row row)
    {
        Object[] cks = row.clustering().kind() == STATIC_CLUSTERING ? null : composeClusterings(row.clustering(), metadata());

View on GitHub (pinned to 88fd0f6a0e)