apache/cassandra · error · InvalidRequestException

Unsupported restriction

Error message

Unsupported restriction: <relation>

What it means

The IS NOT operator in a WHERE clause is only supported when building the statement for a Materialized View (forView == true); ordinary CQL statements cannot use 'column IS NOT NULL' as a restriction. StatementRestrictions throws Unsupported restriction when an IS_NOT relation appears in a regular query.

Solutions

  1. Remove the IS NOT NULL restriction from the CQL statement.
  2. Filter on a concrete value (e.g. col = ?) or use ALLOW FILTERING with a comparison if applicable.
  3. If null exclusion is essential, use a materialized view whose filter includes IS NOT NULL, or model nulls as an empty/sentinel value.

Example fix

// before
SELECT * FROM users WHERE email IS NOT NULL;
// after
SELECT * FROM users WHERE email = 'specific@example.com'; // or query by key / use a secondary table for indexed emails
Defensive patterns

Strategy: validation

Validate before calling

if (cql.matches("(?i).*\\bIS\\s+NOT\\b.*") && !isMaterializedViewDefinition)
    throw new IllegalArgumentException("IS NOT NULL restrictions are only valid in materialized view filters");

Try / catch

try { session.execute(stmt); }
catch (InvalidRequestException e) {
    if (e.getMessage().startsWith("Unsupported restriction")) { /* rewrite query without IS NOT */ }
    else throw e;
}

Prevention

When it happens

Trigger: Issuing a SELECT/INSERT WHERE clause containing 'col IS NOT NULL' against a normal table via CQL or the driver, rather than inside a CREATE MATERIALIZED VIEW filter.

Common situations: Developers coming from SQL try to filter out nulls with IS NOT NULL in Cassandra queries; Cassandra instead requires filtering on non-null values or redesigning the model.

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

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java:230

         *   - IN relation are restricted to row keys (for now) and conflicts with anything else (we could
         *     allow two IN for the same entity but that doesn't seem very useful)
         *   - The value_alias cannot be restricted in any way (we don't support wide rows with indexed value
         *     in CQL so far)
         *   - CONTAINS and CONTAINS_KEY cannot be used with UPDATE or DELETE
         */
        for (Relation relation : whereClause.relations)
        {

            Operator operator = relation.operator();
            if (operator.requiresFilteringOrIndexingFor(ColumnMetadata.Kind.CLUSTERING) && (type.isUpdate() || type.isDelete()))
            {
                throw invalidRequest("Cannot use %s with %s", type, operator);
            }

            if (operator == Operator.IS_NOT)
            {
                if (!forView)
                    throw new InvalidRequestException("Unsupported restriction: " + relation);

                this.notNullColumns.addAll(relation.toRestriction(table, boundNames, owner, allowFiltering).columns());
            }
            else if (operator.requiresIndexing())
            {
                Restriction restriction = relation.toRestriction(table, boundNames, owner, allowFiltering);

                if (!type.allowUseOfSecondaryIndices() || !restriction.hasSupportingIndex(indexRegistry, indexHints))
                    throw invalidRequest("%s restriction is only supported on properly " +
                                                        "indexed columns. %s is not valid.", operator, relation);

                addRestriction(restriction, indexRegistry, indexHints);
            }
            else
            {
                addRestriction(relation.toRestriction(table, boundNames, owner, allowFiltering), indexRegistry, indexHints);
            }
        }

View on GitHub (pinned to 88fd0f6a0e)