{"record":{"id":"c94b76183fa2fe1d","repo":"apache/cassandra","slug":"unsupported-domain-domain","errorCode":null,"errorMessage":"Unsupported domain {domain}","messagePattern":"Unsupported domain (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/service/accord/txn/TxnQuery.java","lineNumber":321,"sourceCode":"            case Key:\n                for (PartitionKey partitionKey : (Seekables<PartitionKey, ?>)keys)\n                {\n                    // TODO (required): This is looking at ClusterMetadata, but not the ClusterMetadata for the specified epoch, just that epoch or later. Need to store ConsensusMigrationState in the global Topologies Accord stores for itself.\n                    if (!ConsensusRequestRouter.instance.isKeyManagedByAccordForReadAndWrite(clusterMetadata, partitionKey.table(), partitionKey.partitionKey()))\n                        return false;\n                }\n                break;\n            case Range:\n                for (accord.primitives.Range range : (Ranges)keys)\n                {\n                    TokenRange tokenRange = (TokenRange)range;\n                    // TODO (required): This is looking at ClusterMetadata, but not the ClusterMetadata for the specified epoch, just that epoch or later. Need to store ConsensusMigrationState in the global Topologies Accord stores for itself.\n                    if (!ConsensusRequestRouter.instance.isRangeManagedByAccordForReadAndWrite(clusterMetadata, tokenRange.table(), tokenRange))\n                        return false;\n                }\n                break;\n            default:\n                throw new IllegalStateException(\"Unsupported domain \" + keys.domain());\n        }\n\n        return true;\n    }\n\n    private static boolean transactionIsSafeToWrite(ClusterMetadata clusterMetadata, Seekables<?, ?> keys)\n    {\n        checkState(keys.domain().isKey(), \"Only key transactions are supported for writes\");\n\n        for (PartitionKey partitionKey : (Seekables<PartitionKey, ?>)keys)\n        {\n            // TODO (required): This is looking at ClusterMetadata, but not the ClusterMetadata for the specified epoch, just that epoch or later. Need to store ConsensusMigrationState in the global Topologies Accord stores for itself.\n            if (!ConsensusRequestRouter.instance.isKeyManagedByAccordForWrite(clusterMetadata, partitionKey.table(), partitionKey.partitionKey()))\n                return false;\n        }\n        return true;\n    }\n}","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/service/accord/txn/TxnQuery.java#L303-L339","documentation":"transactionIsSafeToReadAndWrite checks whether the seekables of a transaction are routed/managed by Accord depending on their domain (Key or Range). If the keys carry any other domain, the switch has no case and an IllegalStateException is thrown as an internal invariant guard.","triggerScenarios":"Calling transactionShouldBeBlocked (which calls transactionIsSafeToReadAndWrite) with a transaction whose Seekables domain is neither Key nor Range — e.g. after adding a new domain type or passing key-based seekables wrapped in an unexpected container.","commonSituations":"Development of new Accord seekable types; version-skew during upgrade where a node receives transactions with domains it does not know; bugs in transaction construction that set the wrong domain.","solutions":["Add a case for the unsupported Domain in the switch in transactionIsSafeToReadAndWrite","Verify the transaction's seekables were built with Domain.Key or Domain.Range","Check cluster version consistency so all nodes share the same Domain enum"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!EnumSet.of(Domain.Key, Domain.Range).contains(seekables.domain()))\n    throw new IllegalArgumentException(\"Transaction seekables domain unsupported: \" + seekables.domain());","typeGuard":"static boolean isRoutableDomain(Seekables<?, ?> keys) {\n    return keys.domain() == Domain.Key || keys.domain() == Domain.Range;\n}","tryCatchPattern":"try { blocked = transactionShouldBeBlocked(txn, ...); }\ncatch (IllegalStateException e) { /* unknown domain — treat as must-block and investigate */ }","preventionTips":["Fail fast at transaction construction: validate seekables domain before submission","Update every switch over Seekables.domain() when extending Domain","Run mixed-version upgrade tests that exercise all domains"],"tags":["accord","routing","domain-dispatch"],"backgroundTag":"invalid-enum-value","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"}