apache/cassandra · error · InvalidRequestException

read_repair must be set to 'NONE' for transiently…

Error message

read_repair must be set to 'NONE' for transiently replicated keyspaces

What it means

Tables in keyspaces that use transient replication (any DC with transient_replication > 0) must disable read repair, because read repair cannot reconcile transiently-repaired data correctly. Creating such a table with read_repair set to anything other than NONE is rejected.

Solutions

  1. Set read_repair = 'NONE' in the table options: CREATE TABLE ks.t (...) WITH read_repair = 'NONE';
  2. Remove transient replication from the keyspace if read repair is required: recreate keyspace with full RF per DC.
  3. Update schema-migration templates to emit read_repair = 'NONE' for transiently replicated keyspaces.

Example fix

// before
CREATE TABLE ks.t (id int PRIMARY KEY) WITH read_repair = 'BLOCKING';

// after
CREATE TABLE ks.t (id int PRIMARY KEY) WITH read_repair = 'NONE';
Defensive patterns

Strategy: validation

Validate before calling

if (keyspaceUsesTransientReplication(ks) && tableOptions.getOrDefault("read_repair", "NONE") != "NONE") throw new IllegalArgumentException("Set read_repair = 'NONE' for transient keyspaces");

Try / catch

try { session.execute(ddl); } catch (InvalidQueryException e) { if (e.getMessage().contains("read_repair must be set to 'NONE'")) { /* add WITH read_repair = 'NONE' or drop transient replication */ } else throw e; }

Prevention

When it happens

Trigger: `CREATE TABLE ks.t (...) WITH read_repair = 'BLOCKING'` (or 'PARALLEL'/default NONBLOCKING) inside a keyspace whose replication strategy hasTransientReplicas() — checked in apply() after table validation.

Common situations: Adopting transient replication for storage savings while keeping legacy table defaults; copying table options from non-transient keyspaces; older scripts that explicitly set read_repair.

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/97e10c6bb508cbae. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/cql3/statements/schema/CreateTableStatement.java:182

        UserFunctions.Builder ufBuilder = UserFunctions.builder().add();
        for (KeyspaceMetadata ksm : schema)
            ufBuilder.add(ksm.userFunctions);

        TableMetadata.Builder builder = builder(keyspace.types, ufBuilder.build()).epoch(metadata.nextEpoch());

        // We do not want to set table ID here just yet, since we are using CQL for serialising a fully expanded CREATE TABLE statement.
        expandedCql = builder.build().toCqlString(false, attrs.hasProperty(TableAttributes.ID), ifNotExists);
        verifyExpandedCql(expandedCql);

        if (!attrs.hasProperty(TableAttributes.ID))
            builder.id(TableId.get(metadata));
        TableMetadata table = builder.build();
        table.validate();

        if (keyspace.replicationStrategy.hasTransientReplicas()
            && table.params.readRepair != ReadRepairStrategy.NONE)
        {
            throw ire("read_repair must be set to 'NONE' for transiently replicated keyspaces");
        }

        if (!table.params.compression.isEnabled() && !SchemaConstants.isSystemKeyspace(table.keyspace))
            Guardrails.uncompressedTablesEnabled.ensureEnabled(state);

        if (table.params.transactionalMode.accordIsEnabled && SchemaConstants.isSystemKeyspace(keyspaceName))
            throw ire("Cannot enable accord on system tables (%s.%s)", keyspaceName, tableName);

        if (table.params.transactionalMode.accordIsEnabled && !DatabaseDescriptor.getAccordTransactionsEnabled())
            throw ire(format("Cannot create table %s.%s with transactional mode %s with accord.enabled set to false",
                             keyspaceName, tableName, table.params.transactionalMode));

        if (table.params.transactionalMigrationFrom.isMigrating())
            throw ire("Cannot set transactional migration on new tables (%s.%s), %s", keyspaceName, tableName, table.params.transactionalMigrationFrom);

        return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.tables.with(table)));
    }

View on GitHub (pinned to 88fd0f6a0e)