apache/cassandra · error · IllegalArgumentException

Invalid sstable file

Error message

Invalid sstable file ${name}: cannot extract keyspace and table name from %s; make sure the sstable is in the proper sub-directories

What it means

Newer Cassandra layouts store sstables in keyspace/table subdirectories, and fromFileWithComponent derives the keyspace and table names from the file's path. When validateDirs is true and the directory structure does not yield both names, this invalidSSTable exception is thrown, telling you the sstable is not in the proper sub-directories.

Solutions

  1. Move the sstable back into the proper data/<keyspace>/<table>-<id>/ sub-directory layout.
  2. Pass validateDirs=false if you can supply keyspace/table another way (use the non-validating overload carefully).
  3. Use the official backup/restore (e.g. medusa, snapshots) tooling that preserves the directory structure.
  4. Rename the file and place it under the target table's directory matching the name-derived keyspace/table.

Example fix

// before
/var/lib/cassandra/data/md-1g-big-Data.db           // flat path -> thrown
// after
/var/lib/cassandra/data/myks/mytable-md-1g-big-Data.db  // proper keyspace/table sub-dirs
Defensive patterns

Strategy: validation

Validate before calling

File dir = file.getParentFile();
// require .../data/<keyspace>/<table[-uuid]>/<sstable>
boolean ok = dir != null && dir.getParentFile() != null && dir.getParentFile().getParentFile() != null
          && dir.getParentFile().getParentFile().getName().equals("data");

Try / catch

try { Pair<Descriptor, Component> p = Descriptor.fromFileWithComponent(file, true); }
catch (Throwable e) { if (e.getMessage() != null && e.getMessage().contains("cannot extract keyspace and table name")) { /* restore proper dir layout */ } else throw e; }

Prevention

When it happens

Trigger: Descriptor.fromFileWithComponent(file, validateDirs=true) on an sstable sitting in a flat data directory, a backup/restore location, or a manually moved path without the expected data/<keyspace>/<table>-<uuid>/ layout.

Common situations: Manual sstable copies after backup/restore that flatten the directory tree; moving sstables between nodes without preserving layout; running sstable utilities on files extracted to a temp directory.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/io/sstable/Descriptor.java:365

        if (!sstableDirMatcher.find(0))
        {
            sstableDirMatcher = LEGACY_SSTABLE_DIR_PATTERN.matcher(file.toString());
        }

        if (sstableDirMatcher.find(0))
        {
            keyspaceName = sstableDirMatcher.group("keyspace");
            tableName = sstableDirMatcher.group("tableName");
            String indexName = sstableDirMatcher.group("indexName");
            if (indexName != null)
            {
                tableName = String.format("%s.%s", tableName, indexName);
            }
        }
        else if (validateDirs)
        {
            logger.debug("Could not extract keyspace/table info from sstable directory {}", file.toString());
            throw invalidSSTable(name, String.format("cannot extract keyspace and table name from %s; make sure the sstable is in the proper sub-directories", file));
        }

        return Pair.create(new Descriptor(info.version, parentOf(name, file), keyspaceName, tableName, info.id), info.component);
    }

    /**
     * Parse a sstable filename, extracting both the {@code Descriptor} and {@code Component} part.
     *
     * @param file     the {@code File} object for the filename to parse.
     * @param keyspace The keyspace name of the file. If <code>null</code>, then the keyspace name will be extracted
     *                 from the directory path.
     * @param table    The table name of the file. If <code>null</code>, then the table name will be extracted from the
     *                 directory path.
     * @return a pair of the descriptor and component corresponding to the provided {@code file}.
     * @throws IllegalArgumentException if the provided {@code file} does point to a valid sstable filename. This could
     *                                  mean either that the filename doesn't look like a sstable file, or that it is for an old and unsupported
     *                                  versions.
     */

View on GitHub (pinned to 88fd0f6a0e)