apache/cassandra · error · InvalidRequestException
Cannot set default_time_to_live for a materialized view. Dat
Error message
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.
What it means
default_time_to_live cannot be set on a materialized view. View rows are derived from base rows and must expire exactly when the corresponding base data expires; an independent TTL would create inconsistencies between base table and view.
Source
Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java:345
// 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.");
}
/*
* Build the thing
*/
TableMetadata.Builder builder = TableMetadata.builder(keyspaceName, viewName);
if (attrs.hasProperty(TableAttributes.ID))
builder.id(attrs.getId());
else if (!builder.hasId())
builder.id(TableId.get(metadata));
builder.params(attrs.asNewTableParams(keyspaceName))
.kind(TableMetadata.Kind.VIEW);
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Remove default_time_to_live from the view's WITH options.
- Set default_time_to_live on the BASE table; view data will expire with the base data.
- Use per-insert TTLs on base writes; they propagate to view rows automatically.
Example fix
// before CREATE MATERIALIZED VIEW mv AS SELECT ... PRIMARY KEY (...) WITH default_time_to_live = 86400; // after CREATE MATERIALIZED VIEW mv AS SELECT ... PRIMARY KEY (...); // TTL comes from the base table
Defensive patterns
Strategy: validation
Validate before calling
if (viewOptions.containsKey("default_time_to_live") && !viewOptions.get("default_time_to_live").equals("0"))
throw new IllegalArgumentException("do not set default_time_to_live on a materialized view"); Prevention
- Only use view WITH options like CLUSTERING ORDER BY and compaction settings.
- Apply TTL policy on the base table.
When it happens
Trigger: CREATE MATERIALIZED VIEW ... WITH default_time_to_live = N where N != 0.
Common situations: Users copy table WITH options (including default_time_to_live) onto a view definition, expecting per-view TTL control.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Forbidden default_time_to_live detected for a materialized v
- Load CIDR groups cache operation not supported by %s
- 'Get CIDR groups for IP' operation not supported by %s
- ACCESS TO DATACENTERS operations not supported by AllowAllNe
- Remote configuration of auth caches is disabled
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/186eeee2ed61e1fe.
Report an issue: GitHub.