apache/cassandra · error · IllegalArgumentException

String ' ' is not a valid UUID based sstable identifier

Error message

String '${s}' is not a valid UUID based sstable identifier

What it means

UUIDBasedSSTableId.Builder.fromString parses the string form of a UUID-based sstable identifier (format: base36 groups matching ([0-9a-z]{4})_([0-9a-z]{4})_([0-9a-z]{5})([0-9a-z]{13}), 26 chars total) and throws IllegalArgumentException when the string does not match the pattern (src/java/org/apache/cassandra/io/sstable/UUIDBasedSSTableId.java:145). It is the strict parser behind SSTableId creation from filenames/stream metadata.

Solutions

  1. Validate the string first with UUIDBasedSSTableId.Builder.instance.isUniqueIdentifier(s) before calling fromString
  2. Confirm the id comes from a UUID-based sstable generation; if the file is generation-based (e.g. 'mc-1-big-Data.db'), use the legacy generation format instead
  3. Trim whitespace and ensure you pass only the identifier portion (26 chars, base36 groups separated by underscores)
  4. Check that the sstable format/identifier-type configuration matches between writer and reader nodes (sstable.identifier format changes across major versions)

Example fix

// before
SSTableId id = UUIDBasedSSTableId.Builder.instance.fromString(fileName);
// after
if (!UUIDBasedSSTableId.Builder.instance.isUniqueIdentifier(fileName)) {
    throw new IllegalArgumentException("not a UUID-based sstable id: " + fileName);
}
SSTableId id = UUIDBasedSSTableId.Builder.instance.fromString(fileName);
Defensive patterns

Strategy: validation

Validate before calling

if (!UUIDBasedSSTableId.Builder.instance.isUniqueIdentifier(candidate))
    throw new IllegalArgumentException("invalid UUID-based sstable identifier: " + candidate);

Type guard

static boolean isUuidSSTableId(String s) {
    return s != null && java.util.regex.Pattern.matches("(?i)[0-9a-z]{4}_[0-9a-z]{4}_[0-9a-z]{5}[0-9a-z]{13}", s);
}

Try / catch

try {
    return builder.fromString(s);
} catch (IllegalArgumentException e) {
    logger.warn("unparseable sstable id: {}", s);
    return null;
}

Prevention

When it happens

Trigger: Calling fromString with a string that is not a UUID-based identifier: an old-generation ('generation-based') sstable filename id, a truncated/malformed id, whitespace or uppercase-incompatible chars, or a random-UUID-style identifier that doesn't fit the time-UUID base36 encoding.

Common situations: Mixing sstable identifier formats across Cassandra versions (e.g. 3.x/4.0 generation-based files vs 4.1+/5.0 UUID-based ids); parsing filenames from a different table or format manually; passing a component name or column-family directory name instead of the unique-identifier substring.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/io/sstable/UUIDBasedSSTableId.java:145

        @Override
        public boolean isUniqueIdentifier(String str)
        {
            return str != null && str.length() == STRING_LEN && PATTERN.matcher(str).matches();
        }

        @Override
        public boolean isUniqueIdentifier(ByteBuffer bytes)
        {
            return bytes != null && bytes.remaining() == BYTES_LEN;
        }

        @Override
        public UUIDBasedSSTableId fromString(@Nonnull String s) throws IllegalArgumentException
        {
            Matcher m = PATTERN.matcher(s);
            if (!m.matches())
                throw new IllegalArgumentException("String '" + s + "' is not a valid UUID based sstable identifier");

            long dayPart = Long.parseLong(m.group(1), 36);
            long secondPart = Long.parseLong(m.group(2), 36);
            long nanoPart = Long.parseLong(m.group(3), 36);
            long ts = (dayPart * 86_400 + secondPart) * 10_000_000 + nanoPart;
            long randomPart = Long.parseUnsignedLong(m.group(4), 36);

            TimeUUID uuid = new TimeUUID(ts, randomPart);
            return new UUIDBasedSSTableId(uuid);
        }

        @Override
        public UUIDBasedSSTableId fromBytes(@Nonnull ByteBuffer bytes) throws IllegalArgumentException
        {
            Preconditions.checkArgument(bytes.remaining() == UUIDBasedSSTableId.BYTES_LEN, "Buffer does not have a valid number of bytes remaining. Expecting: %s but was: %s", UUIDBasedSSTableId.BYTES_LEN, bytes.remaining());
            bytes = bytes.order() == ByteOrder.BIG_ENDIAN ? bytes : bytes.duplicate().order(ByteOrder.BIG_ENDIAN);
            TimeUUID uuid = new TimeUUID(bytes.getLong(0), bytes.getLong(Long.BYTES));
            return new UUIDBasedSSTableId(uuid);

View on GitHub (pinned to 88fd0f6a0e)