apache/cassandra · error · IllegalStateException
Unhandled domain
Error message
Unhandled domain {domain} What it means
TxnRead.empty() returns the singleton empty read for the given Domain. The switch handles Key and Range and places the throw in the default branch, so any other/unrecognized Domain value throws IllegalStateException. It is an internal exhaustiveness guard.
Solutions
- Add a case for the new Domain constant returning an appropriate empty TxnRead
- Ensure createTxnRead only calls empty() with Key or Range domains
- Check for version skew across the cluster
Example fix
// before
default:
throw new IllegalStateException("Unhandled domain " + domain);
// after
case Range:
return EMPTY_RANGE;
default:
throw new IllegalStateException("Unhandled domain " + domain); Defensive patterns
Strategy: validation
Validate before calling
if (domain != Domain.Key && domain != Domain.Range)
throw new IllegalArgumentException("TxnRead.empty only supports Key or Range, got " + domain); Type guard
static boolean isEmptySupported(Domain domain) {
return domain == Domain.Key || domain == Domain.Range;
} Try / catch
try { TxnRead r = TxnRead.empty(domain); }
catch (IllegalStateException e) { /* unknown domain — inspect createTxnRead inputs */ } Prevention
- Only derive the domain from the txn's seekables, never from unvalidated input
- Cover all Domain values in unit tests for TxnRead factories
When it happens
Trigger: Calling TxnRead.empty(domain) with a Domain other than Key or Range — e.g. from createTxnRead when the txn's seekables domain is a newly added or corrupted value.
Common situations: Adding a new Domain enum constant without updating TxnRead; deserialization of a transaction from a node running different code; logic errors in createTxnRead deriving the 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
- Cannot serialize RedundantStatus larger than 0xFFFF…
- Corrupted input: expected byte 1, 2, 3, 4, 5 or 6; received
- Corrupted input: expected byte 1, 2, 3, 4 or 5; received
- Corrupted input: expected byte 1 or 2, received " + b
- No serializer exists for kind
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/29cdd54fc86f39ec.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/service/accord/txn/TxnRead.java:96
import static org.apache.cassandra.utils.NullableSerializer.serializeNullable;
import static org.apache.cassandra.utils.NullableSerializer.serializedNullableSize;
public class TxnRead extends AbstractKeySorted<TxnNamedRead> implements Read
{
private static final TxnRead EMPTY_KEY = new TxnRead(TableMetadatas.none(), Domain.Key);
private static final TxnRead EMPTY_RANGE = new TxnRead(TableMetadatas.none(), Domain.Range);
private static final long EMPTY_SIZE = ObjectSizes.measure(EMPTY_KEY);
private static final Comparator<TxnNamedRead> TXN_NAMED_READ_KEY_COMPARATOR = Comparator.comparing(a -> ((PartitionKey) a.key()));
private static final byte TYPE_EMPTY_KEY = 0;
private static final byte TYPE_EMPTY_RANGE = 1;
private static final byte TYPE_NOT_EMPTY = 2;
public static TxnRead empty(Domain domain)
{
switch (domain)
{
default:
throw new IllegalStateException("Unhandled domain " + domain);
case Key:
return EMPTY_KEY;
case Range:
return EMPTY_RANGE;
}
}
final TableMetadatas tables;
// Cassandra's consistency level used by Accord to safely read data written outside of Accord
@Nullable
private final ConsistencyLevel cassandraConsistencyLevel;
// Specifies the domain in case the TxnRead is empty and it can't be inferred
private final Domain domain;
private TxnRead(TableMetadatas tables, Domain domain)
{
super(new TxnNamedRead[0], domain);View on GitHub (pinned to 88fd0f6a0e)