apache/cassandra · error · IllegalStateException

Unsupported domain

Error message

Unsupported domain {domain}

What it means

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.

Solutions

  1. Add a case for the unsupported Domain in the switch in transactionIsSafeToReadAndWrite
  2. Verify the transaction's seekables were built with Domain.Key or Domain.Range
  3. Check cluster version consistency so all nodes share the same Domain enum
Defensive patterns

Strategy: validation

Validate before calling

if (!EnumSet.of(Domain.Key, Domain.Range).contains(seekables.domain()))
    throw new IllegalArgumentException("Transaction seekables domain unsupported: " + seekables.domain());

Type guard

static boolean isRoutableDomain(Seekables<?, ?> keys) {
    return keys.domain() == Domain.Key || keys.domain() == Domain.Range;
}

Try / catch

try { blocked = transactionShouldBeBlocked(txn, ...); }
catch (IllegalStateException e) { /* unknown domain — treat as must-block and investigate */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/service/accord/txn/TxnQuery.java:321

            case Key:
                for (PartitionKey partitionKey : (Seekables<PartitionKey, ?>)keys)
                {
                    // 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.
                    if (!ConsensusRequestRouter.instance.isKeyManagedByAccordForReadAndWrite(clusterMetadata, partitionKey.table(), partitionKey.partitionKey()))
                        return false;
                }
                break;
            case Range:
                for (accord.primitives.Range range : (Ranges)keys)
                {
                    TokenRange tokenRange = (TokenRange)range;
                    // 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.
                    if (!ConsensusRequestRouter.instance.isRangeManagedByAccordForReadAndWrite(clusterMetadata, tokenRange.table(), tokenRange))
                        return false;
                }
                break;
            default:
                throw new IllegalStateException("Unsupported domain " + keys.domain());
        }

        return true;
    }

    private static boolean transactionIsSafeToWrite(ClusterMetadata clusterMetadata, Seekables<?, ?> keys)
    {
        checkState(keys.domain().isKey(), "Only key transactions are supported for writes");

        for (PartitionKey partitionKey : (Seekables<PartitionKey, ?>)keys)
        {
            // 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.
            if (!ConsensusRequestRouter.instance.isKeyManagedByAccordForWrite(clusterMetadata, partitionKey.table(), partitionKey.partitionKey()))
                return false;
        }
        return true;
    }
}

View on GitHub (pinned to 88fd0f6a0e)