{"record":{"id":"5248218c6a7394f2","repo":"apache/cassandra","slug":"string-s-is-not-a-valid-uuid-based-sstable-id","errorCode":null,"errorMessage":"String '${s}' is not a valid UUID based sstable identifier","messagePattern":"String '(.+?)' is not a valid UUID based sstable identifier","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/sstable/UUIDBasedSSTableId.java","lineNumber":145,"sourceCode":"\n        @Override\n        public boolean isUniqueIdentifier(String str)\n        {\n            return str != null && str.length() == STRING_LEN && PATTERN.matcher(str).matches();\n        }\n\n        @Override\n        public boolean isUniqueIdentifier(ByteBuffer bytes)\n        {\n            return bytes != null && bytes.remaining() == BYTES_LEN;\n        }\n\n        @Override\n        public UUIDBasedSSTableId fromString(@Nonnull String s) throws IllegalArgumentException\n        {\n            Matcher m = PATTERN.matcher(s);\n            if (!m.matches())\n                throw new IllegalArgumentException(\"String '\" + s + \"' is not a valid UUID based sstable identifier\");\n\n            long dayPart = Long.parseLong(m.group(1), 36);\n            long secondPart = Long.parseLong(m.group(2), 36);\n            long nanoPart = Long.parseLong(m.group(3), 36);\n            long ts = (dayPart * 86_400 + secondPart) * 10_000_000 + nanoPart;\n            long randomPart = Long.parseUnsignedLong(m.group(4), 36);\n\n            TimeUUID uuid = new TimeUUID(ts, randomPart);\n            return new UUIDBasedSSTableId(uuid);\n        }\n\n        @Override\n        public UUIDBasedSSTableId fromBytes(@Nonnull ByteBuffer bytes) throws IllegalArgumentException\n        {\n            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());\n            bytes = bytes.order() == ByteOrder.BIG_ENDIAN ? bytes : bytes.duplicate().order(ByteOrder.BIG_ENDIAN);\n            TimeUUID uuid = new TimeUUID(bytes.getLong(0), bytes.getLong(Long.BYTES));\n            return new UUIDBasedSSTableId(uuid);","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/sstable/UUIDBasedSSTableId.java#L127-L163","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Validate the string first with UUIDBasedSSTableId.Builder.instance.isUniqueIdentifier(s) before calling fromString","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","Trim whitespace and ensure you pass only the identifier portion (26 chars, base36 groups separated by underscores)","Check that the sstable format/identifier-type configuration matches between writer and reader nodes (sstable.identifier format changes across major versions)"],"exampleFix":"// before\nSSTableId id = UUIDBasedSSTableId.Builder.instance.fromString(fileName);\n// after\nif (!UUIDBasedSSTableId.Builder.instance.isUniqueIdentifier(fileName)) {\n    throw new IllegalArgumentException(\"not a UUID-based sstable id: \" + fileName);\n}\nSSTableId id = UUIDBasedSSTableId.Builder.instance.fromString(fileName);","handlingStrategy":"validation","validationCode":"if (!UUIDBasedSSTableId.Builder.instance.isUniqueIdentifier(candidate))\n    throw new IllegalArgumentException(\"invalid UUID-based sstable identifier: \" + candidate);","typeGuard":"static boolean isUuidSSTableId(String s) {\n    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);\n}","tryCatchPattern":"try {\n    return builder.fromString(s);\n} catch (IllegalArgumentException e) {\n    logger.warn(\"unparseable sstable id: {}\", s);\n    return null;\n}","preventionTips":["Extract exactly the identifier substring from filenames before parsing","Handle both generation-based and UUID-based ids depending on sstable format version","Never hand-construct identifier strings; generate them via the Builder generator"],"tags":["cassandra","sstable","parsing","identifier"],"backgroundTag":"invalid-identifier-format","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"}