apache/cassandra · error · IllegalArgumentException
Conditional statements are not supported
Error message
Conditional statements are not supported
What it means
StressCQLSSTableWriter prepares the user-provided INSERT for offline SSTable generation, which cannot honor lightweight transactions. prepareInsert() inspects the parsed UpdateStatement and throws IllegalArgumentException if hasConditions() is true (e.g. IF NOT EXISTS or IF col = x).
Solutions
- Remove IF NOT EXISTS / IF conditions from the insert statement.
- Ensure row uniqueness in your data instead of relying on LWT semantics.
- Use a plain INSERT with the full primary key and all columns.
- Pre-deduplicate input rows before writing if overwrites are a concern.
Example fix
// before
builder.using("INSERT INTO ks.tbl (k, v) VALUES (?, ?) IF NOT EXISTS");
// after
builder.using("INSERT INTO ks.tbl (k, v) VALUES (?, ?)"); Defensive patterns
Strategy: validation
Validate before calling
String cql = insertStmt.trim().toLowerCase();
if (cql.contains(" if ") || cql.contains("if not exists")) throw new IllegalArgumentException("conditions not allowed in SSTable writer");
builder.using(insertStmt); Try / catch
try { writer = builder.build(); }
catch (IllegalArgumentException e) { throw new IllegalStateException("strip IF conditions from insert: " + e.getMessage(), e); } Prevention
- Never reuse application LWT statements for bulk SSTable generation.
- Enforce uniqueness in source data instead of IF NOT EXISTS.
- Review generated CQL for condition keywords before use.
- Document that the writer accepts plain writes only.
When it happens
Trigger: Passing an INSERT with IF NOT EXISTS or an UPDATE with IF <condition> to builder.using(...) (via preparedInsert).
Common situations: Reusing an application LWT insert statement directly for bulk loading; copying production CQL that uses conditional writes for idempotency; ORM-generated inserts with IF NOT EXISTS defaults.
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
- Counter update statements are not supported
- Counter columns cannot be accessed within a transaction;
- Provided insert statement has no bind variables
- 3
- A range supplied to SSTableCursorReader ends before it…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/50562334fa537116.
Report an issue: GitHub.
Appendix: source
Thrown at tools/stress/src/org/apache/cassandra/io/sstable/StressCQLSSTableWriter.java:700
private static TableId deterministicId(String keyspace, String table)
{
return TableId.fromUUID(UUID.nameUUIDFromBytes(ArrayUtils.addAll(keyspace.getBytes(), table.getBytes())));
}
/**
* Prepares insert statement for writing data to SSTable
*
* @return prepared Insert statement and it's bound names
*/
private UpdateStatement prepareInsert()
{
ClientState state = ClientState.forInternalCalls();
CQLStatement cqlStatement = insertStatement.prepare(state);
UpdateStatement insert = (UpdateStatement) cqlStatement;
insert.validate(state);
if (insert.hasConditions())
throw new IllegalArgumentException("Conditional statements are not supported");
if (insert.isCounter())
throw new IllegalArgumentException("Counter update statements are not supported");
if (insert.getBindVariables().isEmpty())
throw new IllegalArgumentException("Provided insert statement has no bind variables");
return insert;
}
}
public static <T extends CQLStatement.Raw> T parseStatement(String query, Class<T> klass, String type)
{
try
{
CQLStatement.Raw stmt = CQLFragmentParser.parseAnyUnhandled(CqlParser::query, query);
if (!stmt.getClass().equals(klass))
throw new IllegalArgumentException("Invalid query, must be a " + type + " statement but was: " + stmt.getClass());
View on GitHub (pinned to 88fd0f6a0e)