apache/cassandra · error · InvalidRequestException

Non-primary key columns can only be restricted with 'IS NOT…

Error message

Non-primary key columns can only be restricted with 'IS NOT NULL' (got: %s restricted illegally)

What it means

In a materialized view's WHERE clause, non-primary-key columns may only be restricted with IS NOT NULL (unless the unsafe flag MV_ALLOW_FILTERING_NONKEY_COLUMNS_UNSAFE is enabled). Other predicates on non-key columns would require view rows to be recomputed/moved on updates, which Cassandra refuses.

Solutions

  1. Change the restriction on the non-key column to IS NOT NULL only.
  2. Move the regular column into the view primary key and restrict it (at most one non-PK base column is allowed).
  3. Set the unsafe flag (MV_ALLOW_FILTERING_NONKEY_COLUMNS_UNSAFE) only if you fully understand the consistency implications.
  4. Handle the value filtering at query time on the view.

Example fix

// before
CREATE MATERIALIZED VIEW mv AS SELECT id, status FROM t WHERE status = 'active' PRIMARY KEY (id, status);
// after
CREATE MATERIALIZED VIEW mv AS SELECT id, status FROM t WHERE id IS NOT NULL PRIMARY KEY (id, status);
// then query with: SELECT * FROM mv WHERE status = 'active';
Defensive patterns

Strategy: validation

Validate before calling

for (ColumnMetadata col : restrictedColumns) {
    if (!col.isPrimaryKeyColumn() && !restrictionIsNotNullOnly(col))
        throw new IllegalArgumentException("non-PK column " + col.name + " may only be restricted with IS NOT NULL");
}

Prevention

When it happens

Trigger: CREATE MATERIALIZED VIEW ... WHERE regular_col = 5 (or any range/inequality on a regular column not in the view primary key), without the unsafe flag set.

Common situations: Users attempt to pre-filter views by value conditions (e.g. status = 'active') on regular columns, expecting SQL-view semantics.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

                                      false,
                                      false,
                                      true,
                                      true);

        List<ColumnIdentifier> nonRestrictedPrimaryKeyColumns =
            Lists.newArrayList(filter(primaryKeyColumns, name -> !restrictions.isRestricted(table.getColumn(name))));

        if (!nonRestrictedPrimaryKeyColumns.isEmpty())
        {
            throw ire("Primary key columns %s must be restricted with 'IS NOT NULL' or otherwise",
                      join(", ", transform(nonRestrictedPrimaryKeyColumns, ColumnIdentifier::toString)));
        }

        // See CASSANDRA-13798
        Set<ColumnMetadata> restrictedNonPrimaryKeyColumns = restrictions.nonPKRestrictedColumns(false);
        if (!restrictedNonPrimaryKeyColumns.isEmpty() && !MV_ALLOW_FILTERING_NONKEY_COLUMNS_UNSAFE.getBoolean())
        {
            throw ire("Non-primary key columns can only be restricted with 'IS NOT NULL' (got: %s restricted illegally)",
                      join(",", transform(restrictedNonPrimaryKeyColumns, ColumnMetadata::toString)));
        }

        /*
         * Validate WITH params
         */

        attrs.validate();

        if (attrs.hasOption(TableParams.Option.DEFAULT_TIME_TO_LIVE)
            && attrs.getInt(TableParams.Option.DEFAULT_TIME_TO_LIVE.toString(), 0) != 0)
        {
            throw ire("Cannot set default_time_to_live for a materialized view. " +
                      "Data in a materialized view always expire at the same time than " +
                      "the corresponding data in the parent table.");
        }

        /*

View on GitHub (pinned to 88fd0f6a0e)