apache/cassandra · error · MarshalException
Invalid UUID version
Error message
Invalid UUID version %d for timeuuid
What it means
verifyVersion checks the UUID version nibble of the high bits and throws when it is not 1. timeuuid values in Cassandra are RFC 4122 version-1 (time-based) UUIDs; any other version stored in a timeuuid column is rejected during comparison or comparable-bytes conversion.
Solutions
- Generate proper version-1 time UUIDs (e.g. UUIDGen.getTimeUUID(), or TimeUUID.Generator) instead of random UUIDs.
- Parse/validate client-side: check uuid.version() == 1 before sending to a timeuuid column.
- Change the column type to uuid if version-4 UUIDs are intended.
Example fix
// before UUID id = UUID.randomUUID(); // version 4 // after UUID id = UUIDGen.getTimeUUID(); // version 1 timeuuid
Defensive patterns
Strategy: validation
Validate before calling
UUID u = /* candidate */;
if (u == null || u.version() != 1) throw new IllegalArgumentException("timeuuid must be version 1"); Type guard
boolean isTimeUUID(java.util.UUID u) { return u != null && u.version() == 1; } Try / catch
catch (MarshalException e) { log.warn("non-v1 uuid in timeuuid column: {}", e.getMessage()); regenerateTimeUUID(); } Prevention
- Use UUIDGen.getTimeUUID() (or the driver's timeuuid generator) for timeuuid columns.
- Never send UUID.randomUUID() to a timeuuid column.
- Centralize UUID creation behind a helper that enforces v1 for timeuuid fields.
When it happens
Trigger: Comparing values of AbstractTimeUUIDType (compareCustom, asComparableBytes) or calling fromComparableBytes with a 16-byte value whose UUID version nibble is not 1 (e.g. version 4 random UUID bytes) stored in a timeuuid column.
Common situations: Inserting a random UUID (java.util.UUID.randomUUID()) into a timeuuid column via raw bytes or drivers that don't validate; application code generating non-v1 UUIDs; corrupted binary data.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- EmptyType only accept empty values
- Expected 4 or 0 byte int
- Expected 4 or 0 byte value for a float
- Expected 4 or 16 byte inetaddress; got
- Argument ' ' cannot be frozen; remove frozen<> modifier from
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/007e59050b9c5891.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/db/marshal/AbstractTimeUUIDType.java:135
// In addition, TimeUUIDType also touches the low bits of the UUID (see CASSANDRA-8730 and DB-1758).
loBits ^= 0x8080808080808080L;
return UUIDType.makeUuidBytes(accessor, hiBits, loBits);
}
// takes as input 8 signed bytes in native machine order
// returns the first byte unchanged, and the following 7 bytes converted to an unsigned representation
// which is the same as a 2's complement long in native format
public static long signedBytesToNativeLong(long signedBytes)
{
return signedBytes ^ 0x0080808080808080L;
}
private void verifyVersion(long hiBits)
{
long version = (hiBits >>> 12) & 0xF;
if (version != 1)
throw new MarshalException(String.format("Invalid UUID version %d for timeuuid",
version));
}
protected static long reorderTimestampBytes(long input)
{
return (input << 48)
| ((input << 16) & 0xFFFF00000000L)
| (input >>> 32);
}
protected static long reorderBackTimestampBytes(long input)
{
// In a time-based UUID the high bits are significantly more shuffled than in other UUIDs - if [X] represents a
// 16-bit tuple, [1][2][3][4] should become [3][4][2][1].
// See the UUID Javadoc (and more specifically the high bits layout of a Leach-Salz UUID) to understand the
// reasoning behind this bit twiddling in the first place (in the context of comparisons).
return (input << 32)
| ((input >>> 16) & 0xFFFF0000L)View on GitHub (pinned to 88fd0f6a0e)