{"record":{"id":"f890c88037a165c9","repo":"apache/cassandra","slug":"transient-replication-is-not-supported-with-vnodes","errorCode":null,"errorMessage":"Transient replication is not supported with vnodes yet","messagePattern":"Transient replication is not supported with vnodes yet","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/AlterKeyspaceStatement.java","lineNumber":202,"sourceCode":"    private void validateTransientReplication(KeyspaceMetadata current, KeyspaceMetadata proposed)\n    {\n        //If there is no read traffic there are some extra alterations you can safely make, but this is so atypical\n        //that a good default is to not allow unsafe changes\n        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","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/AlterKeyspaceStatement.java#L184-L220","documentation":"Transient replication is only supported with single-token-per-node deployments. When a keyspace is altered to use a nonzero transient replication factor on a node configured with more than one token (vnodes), apply-time validation throws this ConfigurationException.","triggerScenarios":"`ALTER KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','dc1':'3/1'}` (transient replicas > 0) while DatabaseDescriptor.getNumTokens() > 1 on the coordinator node.","commonSituations":"Enabling transient replication on a vnode-based cluster (the default install uses num_tokens=16) without first moving to single-token assignment.","solutions":["Remove the transient component (use e.g. '3' instead of '3/1') in the replication options.","Migrate the cluster to a single-token configuration before enabling transient replication.","Keep RF settings purely full replicas on vnode clusters."],"exampleFix":"// before\n\"ALTER KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','dc1':'3/1'}\";\n// after\n\"ALTER KEYSPACE ks WITH replication = {'class':'NetworkTopologyStrategy','dc1':3}\";","handlingStrategy":"validation","validationCode":"if (transientReplicasRequested > 0 && DatabaseDescriptor.getNumTokens() > 1) throw new IllegalArgumentException(\"transient replication requires single-token nodes\");","typeGuard":null,"tryCatchPattern":"try { session.execute(alterKeyspace); } catch (ConfigurationException e) { if (e.getMessage().contains(\"Transient replication is not supported with vnodes\")) stripTransientComponent(replication); else throw e; }","preventionTips":["Know your num_tokens setting before using transient replication","Only apply 'rf/t' syntax on single-token clusters","Validate replication strings in deployment tooling before applying"],"tags":["configuration","transient-replication","vnodes","alter-keyspace"],"backgroundTag":"unsupported-config-value","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"}