apache/cassandra · error · java.lang.IllegalArgumentException
is of version which is now unsupported and cannot be read.
Error message
%s is of version %s which is now unsupported and cannot be read.
What it means
Descriptor.filenameTokens() parses an SSTable file name into tokens and maps them to a supported version. When the token layout matches the legacy pre-3.0 naming scheme <keyspace>-<table>-(tmp-)?<version>-<gen>-<component> (5 or 6 tokens), the extracted version is one Cassandra can no longer read, so it throws IllegalArgumentException naming the file and the detected legacy version to aid migration triage.
Solutions
- Upgrade the data via a supported path: run the old Cassandra version, then upgradesstables before moving to the new version (stepping through intermediate major versions if required)
- Restore old data by exporting/importing (e.g. COPY TO/FROM or sstableloader from the old version) instead of copying files
- Delete or archive the legacy SSTable files if the data is no longer needed so the node stops trying to parse them
Example fix
// before (restoring legacy files directly) cp /backup/ks-cf-jb-12-Data.db /var/lib/cassandra/data/ks/cf-<uuid>/ // after (load via sstableloader from matching version) sstableloader -d newnode /backup/ks/cf
Defensive patterns
Strategy: validation
Validate before calling
String name = file.getName();
if (name.matches("[a-zA-Z0-9_]+-[a-zA-Z0-9_]+-(tmp-)?[a-z]{2}-\\d+-.*"))
throw new IllegalArgumentException("Legacy pre-3.0 sstable, run upgradesstables on an older version first"); Try / catch
try { Descriptor d = Descriptor.fromFilename(file); }
catch (IllegalArgumentException e) {
if (e.getMessage().contains("now unsupported and cannot be read"))
// migrate via upgradesstables or sstableloader
} Prevention
- Complete upgradesstables before retiring each old Cassandra version
- Never copy legacy SSTable files directly into modern data directories
- Audit snapshot/backup contents for old-format file names before restore
When it happens
Trigger: Pointing Cassandra at a data directory containing old-format SSTables (e.g. 'ks-cf-jb-12-Data.db' style names) so Descriptor.fromFilename/fromFileWithComponent parses them, e.g. during startup, nodetool utilities, or upgrades.
Common situations: Upgrading very old clusters in place without running upgradesstables; copying legacy backup SSTables into a modern node's data dir; restoring old snapshots onto a new version.
Related errors
- Can't open incompatible SSTable! Current version
- Cannot DROP COMPACT STORAGE as some nodes in the cluster
- Invalid sstable file
- Invalid sstable file
- Invalid sstable file
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/caa6b67b13153e0f.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/io/sstable/Descriptor.java:408
SSTableInfo info = validateAndExtractInfo(file);
return Pair.create(new Descriptor(info.version, parentOf(file.name(), file), keyspace, table, info.id), info.component);
}
private static List<String> filenameTokens(String name)
{
List<String> tokens = filenameSplitter.splitToList(name);
int size = tokens.size();
if (size != 4)
{
// This is an invalid sstable file for this version. But to provide a more helpful error message, we detect
// old format sstable, which had the format:
// <keyspace>-<table>-(tmp-)?<version>-<gen>-<component>
// Note that we assume it's an old format sstable if it has the right number of tokens: this is not perfect
// but we're just trying to be helpful, not perfect.
if (size == 5 || size == 6)
throw new IllegalArgumentException(String.format("%s is of version %s which is now unsupported and cannot be read.", name, tokens.get(size - 3)));
throw new IllegalArgumentException(String.format("Invalid sstable file %s: the name doesn't look like a supported sstable file name", name));
}
return tokens;
}
private static SSTableInfo validateAndExtractInfo(File file)
{
String name = file.name();
List<String> tokens = filenameTokens(name);
String versionString = tokens.get(0);
if (!Version.validate(versionString))
throw invalidSSTable(name, "invalid version %s", versionString);
SSTableId id;
try
{
id = SSTableIdFactory.instance.fromString(tokens.get(1));View on GitHub (pinned to 88fd0f6a0e)