apache/cassandra · error · InvalidRequestException

Cannot use ALTER TABLE on a materialized view; use ALTER MAT

Error message

Cannot use ALTER TABLE on a materialized view; use ALTER MATERIALIZED VIEW instead

What it means

AlterTableStatement.apply validation: the named table is actually a materialized view, and ALTER TABLE cannot alter views. The statement fails with InvalidRequestException; ALTER MATERIALIZED VIEW must be used instead.

Source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/AlterTableStatement.java:138

        Keyspaces schema = metadata.schema.getKeyspaces();
        KeyspaceMetadata keyspace = schema.getNullable(keyspaceName);

        TableMetadata table = null == keyspace
                            ? null
                            : keyspace.getTableOrViewNullable(tableName);

        if (null == table)
        {
            if (!ifExists)
                throw ire("Table '%s.%s' doesn't exist", keyspaceName, tableName);
            return schema;
        }

        if (table.params.pendingDrop)
            throw ire("Cannot use ALTER TABLE on a table that is being dropped.");

        if (table.isView())
            throw ire("Cannot use ALTER TABLE on a materialized view; use ALTER MATERIALIZED VIEW instead");

        return schema.withAddedOrUpdated(apply(metadata.nextEpoch(), keyspace, table, metadata));
    }

    SchemaChange schemaChangeEvent(KeyspacesDiff diff)
    {
        return new SchemaChange(Change.UPDATED, Target.TABLE, keyspaceName, tableName);
    }

    public void authorize(ClientState client)
    {
        client.ensureTablePermission(keyspaceName, tableName, Permission.ALTER);
    }

    @Override
    public AuditLogContext getAuditLogContext()
    {
        return new AuditLogContext(AuditLogEntryType.ALTER_TABLE, keyspaceName, tableName);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Use ALTER MATERIALIZED VIEW ks.view_name WITH ... to change view properties
  2. If the intent was to change the base table, target the base table name instead
  3. Remember view properties like gc_grace_seconds are changed on the view, not the base table

Example fix

// before
session.execute("ALTER TABLE my_app.events_by_day WITH gc_grace_seconds = 0");
// after
session.execute("ALTER MATERIALIZED VIEW my_app.events_by_day WITH gc_grace_seconds = 0");
Defensive patterns

Strategy: validation

Validate before calling

Row r = session.execute("SELECT kind FROM system_schema.tables WHERE keyspace_name=? AND table_name=?", ks, name).one();
if (r != null && "view".equals(r.getString("kind")))
    throw new IllegalArgumentException(name + " is a materialized view; use ALTER MATERIALIZED VIEW");

Try / catch

try {
    session.execute(alter);
} catch (InvalidRequestException e) {
    if (e.getMessage().contains("materialized view"))
        session.execute(alter.replaceFirst("(?i)ALTER TABLE", "ALTER MATERIALIZED VIEW"));
    else throw e;
}

Prevention

When it happens

Trigger: 'ALTER TABLE ks.view_name ...' where the named table is actually a materialized view — e.g. views created via CREATE MATERIALIZED VIEW appear in the same namespace as tables and getTableOrViewNullable resolves them

Common situations: Altering a view by mistake because its name resembles the base table; automation enumerating all tables from system_schema.tables (views appear there too) and applying the same DDL; renaming refactors that swapped a table for a view.

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/ade3b7ca2763716d. Report an issue: GitHub.