{"record":{"id":"5bda83018fc62c5a","repo":"apache/cassandra","slug":"secondary-indexes-are-not-supported-on-transiently","errorCode":null,"errorMessage":"Secondary indexes are not supported on transiently replicated keyspaces","messagePattern":"Secondary indexes are not supported on transiently replicated keyspaces","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java","lineNumber":178,"sourceCode":"        if (null == table)\n            throw ire(TABLE_DOES_NOT_EXIST, tableName);\n\n        if (null != indexName && keyspace.hasIndex(indexName))\n        {\n            if (ifNotExists)\n                return schema;\n\n            throw ire(INDEX_ALREADY_EXISTS, indexName);\n        }\n\n        if (table.isCounter())\n            throw ire(COUNTER_TABLES_NOT_SUPPORTED);\n\n        if (table.isView())\n            throw ire(MATERIALIZED_VIEWS_NOT_SUPPORTED);\n\n        if (keyspace.replicationStrategy.hasTransientReplicas())\n            throw new InvalidRequestException(TRANSIENTLY_REPLICATED_KEYSPACE_NOT_SUPPORTED);\n\n        // guardrails to limit number of secondary indexes per table.\n        Guardrails.secondaryIndexesPerTable.guard(table.indexes.size() + 1,\n                                                  Strings.isNullOrEmpty(indexName)\n                                                  ? String.format(\"on table %s\", table.name)\n                                                  : String.format(\"%s on table %s\", indexName, table.name),\n                                                  false,\n                                                  state);\n\n        List<IndexTarget> indexTargets = Lists.newArrayList(transform(rawIndexTargets, t -> t.prepare(table)));\n\n        if (indexTargets.isEmpty() && !attrs.isCustom)\n            throw ire(CUSTOM_CREATE_WITHOUT_COLUMN);\n\n        if (indexTargets.size() > 1)\n        {\n            if (!attrs.isCustom)\n                throw ire(CUSTOM_MULTIPLE_COLUMNS);","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateIndexStatement.java#L160-L196","documentation":"Secondary indexes (including custom ones) cannot be created on keyspaces whose replication strategy uses transient replication ( AnyaReplication/network topology with transient replicas). Transient replicas store no full data copy, so index maintenance and read repair semantics are incompatible. The statement checks `keyspace.replicationStrategy.hasTransientReplicas()` and throws InvalidRequestException.","triggerScenarios":"`CREATE [CUSTOM] INDEX ...` targeting a table whose keyspace was created with a replication factor like `txnr`/transient replicas (e.g. `NetworkTopologyStrategy` with a datacenter RF like `3/1`).","commonSituations":"Using transient replication for cost savings and then trying to add a 2i for ad-hoc queries; tooling that auto-creates indexes without checking keyspace replication settings.","solutions":["Remove transient replication from the keyspace (`ALTER KEYSPACE ... WITH replication = {...}` using full replicas) and run a full repair, then create the index.","Create the index in a keyspace that does not use transient replication.","Use a different query strategy (e.g. denormalized table or SAI if applicable per version) that is compatible with transient replication."],"exampleFix":"-- before\ncqlsh> CREATE INDEX ON myks.mytable (col); -- keyspace has transient replicas\n\n-- after\nALTER KEYSPACE myks WITH replication = {'class':'NetworkTopologyStrategy','dc1':3};\n-- nodetool repair -full myks\nCREATE INDEX ON myks.mytable (col);","handlingStrategy":"validation","validationCode":"KeyspaceMetadata ks = session.getCluster().getMetadata().getKeyspace(\"myks\");\nif (ks != null && ks.getReplication().containsKey(\"txnr\") /* transient replicas */)\n    throw new IllegalStateException(\"cannot create 2i on transiently replicated keyspace\");","typeGuard":null,"tryCatchPattern":"try { session.execute(createIndex); }\ncatch (InvalidQueryException e) {\n  if (e.getMessage().contains(\"transiently replicated\"))\n      throw new IllegalStateException(\"ALTER KEYSPACE to full replicas + repair before indexing\", e);\n  throw e;\n}","preventionTips":["Document that transient replication precludes 2i and MVs for a keyspace","Check system_schema keyspaces replication map for 'txnr' before generating index DDL","Automate the ALTER KEYSPACE + repair sequence when removing transient replication"],"tags":["cassandra","secondary-index","transient-replication","replication"],"backgroundTag":"unsupported-operation","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}