apache/cassandra · error · InvalidRequestException

Materialized views are not supported on counter tables

Error message

Materialized views are not supported on counter tables

What it means

Base-table validation in CreateViewStatement.apply(): the underlying table of the new materialized view is a counter table. Materialized views cannot reliably mirror counter updates because view row liveness and counter deltas interact badly, so creating a view over a counter table is rejected with InvalidRequestException.

Solutions

  1. Denormalize counter data into a regular table updated by the application instead of using a materialized view; keep counters in a dedicated table and maintain an aggregate table via application logic or a UDF-free write path; redesign the schema so the view is built over a non-counter table.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java:173 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java:173

            throw ire("Base table '%s' doesn't exist", tableName);

        if (keyspace.hasTable(viewName))
            throw ire("Cannot create materialized view '%s' - a table with the same name already exists", viewName);

        if (keyspace.hasView(viewName))
        {
            if (ifNotExists)
                return schema;

            throw new AlreadyExistsException(keyspaceName, viewName);
        }

        /*
         * Base table validation
         */

        if (table.isCounter())
            throw ire("Materialized views are not supported on counter tables");

        if (table.isView())
            throw ire("Materialized views cannot be created against other materialized views");

        // Guardrails on table properties
        Guardrails.tableProperties.guard(attrs.updatedProperties(), attrs::removeProperty, state);

        // Guardrail to limit number of mvs per table
        Iterable<ViewMetadata> tableViews = keyspace.views.forTable(table.id);
        Guardrails.materializedViewsPerTable.guard(Iterables.size(tableViews) + 1,
                                                   String.format("%s on table %s", viewName, table.name),
                                                   false,
                                                   state);

        if (table.params.gcGraceSeconds == 0)
        {
            throw ire("Cannot create materialized view '%s' for base table " +
                      "'%s' with gc_grace_seconds of 0, since this value is " +

View on GitHub (pinned to 88fd0f6a0e)