apache/cassandra · error · InvalidRequestException
Slice conditions ( ) are not supported on durations
Error message
Slice conditions ( %s ) are not supported on durations
What it means
Cassandra refuses slice comparisons (<, <=, >, >=, CONTAINS-style ranges) against duration values or collections/tuples/UDTs containing durations, because durations have no total ordering (e.g. 1 day vs 24 hours are unequal but incomparable for slicing). The guard in ColumnCondition.Raw throws this when an Operator.isSlice() (and not NEQ) is applied to a duration-referencing type in a condition (IF clause).
Solutions
- Replace the slice condition with an equality or inequality that is allowed (only = and != are supported on durations)
- Store the duration as a numeric value (e.g. milliseconds bigint) if range comparisons are needed
- Check the column type with DESC TABLE and confirm whether durations are nested inside a collection/tuple/UDT; move duration out of the nested type
- Perform the comparison client-side: read the row, compare in application code, then conditionally write
Example fix
// before UPDATE t SET v = 1 WHERE k = 1 IF dur < 5h; // after UPDATE t SET v = 1 WHERE k = 1 IF dur = 5h; -- or store comparable numeric: UPDATE t SET v = 1 WHERE k = 1 IF dur_ms < 18000000;
Defensive patterns
Strategy: validation
Validate before calling
// client-side: only = / != allowed on duration columns
const SLICE_OPS = ['<', '<=', '>', '>='];
if (SLICE_OPS.includes(op) && columnType === 'duration') throw new Error('Use = or != for duration conditions'); Type guard
function isSliceOp(op) { return ['<','<=','>','>='].includes(op); } Prevention
- Never use range operators on duration columns
- Store durations as bigint millis when range filtering is required
- Keep durations out of frozen collections/tuples/UDTs that need slice conditions
When it happens
Trigger: A LWT condition like `IF d > 5h`, `IF c[0] <= 1us`, or any slice operator on a duration column, frozen collection containing durations, tuple containing durations, or UDT containing durations.
Common situations: Developers trying `IF my_duration < 2h` in a conditional UPDATE/INSERT/DELETE, or slice conditions on nested duration-bearing collections; often after converting a counter/timedelta-style field to Cassandra's duration type.
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
- duration type is not supported for PRIMARY KEY column
- Durations are not allowed as map keys:
- Durations are not allowed as map keys
- Durations are not allowed inside sets:
- Durations are not allowed inside sets
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/d8a531642ab24719.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/cql3/conditions/ColumnCondition.java:580
checkFalse(operator == Operator.CONTAINS_KEY && !(receiver.type instanceof MapType),
"Cannot use CONTAINS KEY on non-map column %s", receiver.name);
checkFalse(operator == Operator.CONTAINS && !(receiver.type.isCollection()),
"Cannot use CONTAINS on non-collection column %s", receiver.name);
if (operator == Operator.CONTAINS || operator == Operator.CONTAINS_KEY)
receiver = ((CollectionType<?>) receiver.type).makeCollectionReceiver(receiver, operator == Operator.CONTAINS_KEY);
return values.prepare(keyspace, receiver);
}
private void validateOperationOnDurations(AbstractType<?> type)
{
if (type.referencesDuration() && operator.isSlice() && operator != Operator.NEQ)
{
checkFalse(type.isCollection(), "Slice conditions are not supported on collections containing durations");
checkFalse(type.isTuple(), "Slice conditions are not supported on tuples containing durations");
checkFalse(type.isUDT(), "Slice conditions are not supported on UDTs containing durations");
throw invalidRequest("Slice conditions ( %s ) are not supported on durations", operator);
}
}
/**
* Checks if this raw condition contains bind markers.
* @return {@code true} if this raw condition contains bind markers, {@code false} otherwise.
*/
public boolean containsBindMarkers()
{
return rawExpressions.containsBindMarkers() || values.containsBindMarkers();
}
@VisibleForTesting
public String toCQLString()
{
return operator.buildCQLString(rawExpressions, values);
}
View on GitHub (pinned to 88fd0f6a0e)