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

  1. Remove IF NOT EXISTS / IF conditions from the insert statement.
  2. Ensure row uniqueness in your data instead of relying on LWT semantics.
  3. Use a plain INSERT with the full primary key and all columns.
  4. 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

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


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)