{"record":{"id":"3e11c72c3a3802af","repo":"apache/cassandra","slug":"cannot-use-transient-replication-on-keyspaces-usin","errorCode":null,"errorMessage":"Cannot use transient replication on keyspaces using materialized views","messagePattern":"Cannot use transient replication on keyspaces using materialized views","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/AlterKeyspaceStatement.java","lineNumber":206,"sourceCode":"        if (allow_unsafe_transient_changes)\n            return;\n\n        ReplicationFactor oldRF = current.replicationStrategy.getReplicationFactor();\n        ReplicationFactor newRF = proposed.replicationStrategy.getReplicationFactor();\n\n        int oldTrans = oldRF.transientReplicas();\n        int oldFull = oldRF.fullReplicas;\n        int newTrans = newRF.transientReplicas();\n        int newFull = newRF.fullReplicas;\n\n        if (newTrans > 0)\n        {\n            if (DatabaseDescriptor.getNumTokens() > 1)\n                throw new ConfigurationException(String.format(\"Transient replication is not supported with vnodes yet\"));\n\n\n            if (!current.views.isEmpty())\n                throw new ConfigurationException(\"Cannot use transient replication on keyspaces using materialized views\");\n\n            for (TableMetadata table : current.tables)\n                if (!table.indexes.isEmpty())\n                    throw new ConfigurationException(\"Cannot use transient replication on keyspaces using secondary indexes\");\n        }\n\n        //This is true right now because the transition from transient -> full lacks the pending state\n        //necessary for correctness. What would happen if we allowed this is that we would attempt\n        //to read from a transient replica as if it were a full replica.\n        if (oldFull > newFull && oldTrans > 0)\n            throw new ConfigurationException(\"Can't add full replicas if there are any transient replicas. You must first remove all transient replicas, then change the # of full replicas, then add back the transient replicas\");\n\n        //Don't increase transient replication factor by more than one at a time if changing number of replicas\n        //Just like with changing full replicas it's not safe to do this as you could read from too many replicas\n        //that don't have the necessary data. W/O transient replication this alteration was allowed and it's not clear\n        //if it should be.\n        //This is structured so you can convert as many full replicas to transient replicas as you want.\n        boolean numReplicasChanged = oldTrans + oldFull != newTrans + newFull;","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/AlterKeyspaceStatement.java#L188-L224","documentation":"A keyspace using materialized views cannot enable transient replication: the view write path cannot correctly handle transient replicas, so validation rejects altering a keyspace that has views to a nonzero transient replication factor.","triggerScenarios":"`ALTER KEYSPACE ks WITH replication = {..., 'dc1':'3/1'}` on a keyspace that contains one or more materialized views (current.views not empty).","commonSituations":"Trying to save read capacity with transient replication on a keyspace that also hosts MVs (a common setup for denormalized reads).","solutions":["Move the materialized views to a separate keyspace with normal (non-transient) replication.","Drop the views before enabling transient replication and keep them in a non-transient keyspace.","Use full replication (no '/n' component) for keyspaces with MVs."],"exampleFix":"// before\n\"ALTER KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','dc1':'3/1'}\"; // ks has MVs\n// after\n\"ALTER KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','dc1':3}\"; // or move MVs out","handlingStrategy":"validation","validationCode":"KeyspaceMetadata ksm = Schema.instance.getKeyspaceMetadata(ks); if (!ksm.views.isEmpty() && wantsTransient) throw new IllegalArgumentException(\"disable transient RF for keyspaces with MVs\");","typeGuard":null,"tryCatchPattern":"try { session.execute(alterKeyspace); } catch (ConfigurationException e) { if (e.getMessage().contains(\"transient replication on keyspaces using materialized views\")) moveViewsToSeparateKeyspace(); else throw e; }","preventionTips":["Keep MVs in a dedicated keyspace without transient replication","Audit keyspaces for views before enabling transient replication","Remember 2i has the same restriction"],"tags":["configuration","transient-replication","materialized-view","alter-keyspace"],"backgroundTag":"conflicting-config-options","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}