apache/cassandra · error · java.lang.IllegalArgumentException

Conditional statements are not supported

Error message

Conditional statements are not supported

What it means

CQLSSTableWriter is a bulk-loading API that translates an INSERT/UPDATE bind into direct SSTable writes; it bypasses the normal write path, so Lightweight Transaction (LWT) conditions (IF ... EXISTS etc.) cannot be honored. When preparing the user-supplied modification statement, if preparedModificationStatement.hasConditions() the Builder throws IllegalArgumentException to reject conditional statements up front.

Solutions

  1. Remove the conditional clause (IF NOT EXISTS / IF <condition>) from the statement used with CQLSSTableWriter
  2. Ensure uniqueness out-of-band: check for existing keys beforehand or deduplicate the input data before loading
  3. Use the regular driver/LWT path instead of CQLSSTableWriter if conditional semantics are required

Example fix

// before
String cql = "INSERT INTO ks.t (k, v) VALUES (?, ?) IF NOT EXISTS";
// after
String cql = "INSERT INTO ks.t (k, v) VALUES (?, ?)";
Defensive patterns

Strategy: validation

Validate before calling

if (cql.toUpperCase().matches(".*\\bIF\\s+(NOT\\s+EXISTS|.*=).*"))
    throw new IllegalArgumentException("CQLSSTableWriter does not support conditional statements");

Try / catch

try { builder.build(); }
catch (IllegalArgumentException e) {
    if (e.getMessage().equals("Conditional statements are not supported"))
        // strip IF clause and rebuild
}

Prevention

When it happens

Trigger: Passing a statement containing conditions to CQLSSTableWriter.builder().withPreparedStatement / RawStatement-based builders — e.g. 'INSERT INTO t ... IF NOT EXISTS' or 'UPDATE t ... IF col = x' — then calling build().

Common situations: Reusing application CQL strings that use LWT for idempotency inside a bulk-load script; copying statements from a coordinator path into an offline SSTable writer.

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/4b9aaf7413a9214a. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/io/sstable/CQLSSTableWriter.java:917

            if (partitioner != null)
                builder.partitioner(partitioner);

            return builder.build();
        }

        /**
         * Prepares modification statement for writing data to SSTable
         *
         * @return prepared modification statement and it's bound names
         */
        private ModificationStatement prepareModificationStatement()
        {
            ClientState state = ClientState.forInternalCalls();
            ModificationStatement preparedModificationStatement = modificationStatement.prepare(state);
            preparedModificationStatement.validate(state);

            if (preparedModificationStatement.hasConditions())
                throw new IllegalArgumentException("Conditional statements are not supported");
            if (preparedModificationStatement.isCounter())
                throw new IllegalArgumentException("Counter modification statements are not supported");
            if (preparedModificationStatement.getBindVariables().isEmpty())
                throw new IllegalArgumentException("Provided preparedModificationStatement statement has no bind variables");

            return preparedModificationStatement;
        }
    }
}

View on GitHub (pinned to 88fd0f6a0e)