apache/cassandra · error · RuntimeException

Unable to list directory

Error message

Unable to list directory 

What it means

Thrown by maybeRestoreArchive() when a configured restore directory cannot be listed: File.tryList() returned null, meaning the path is not a readable directory (does not exist, is a file, or lacks read permission). Restore cannot proceed without enumerating the archived segments.

Source

Thrown at src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java:281

                }
            }
            throw new RuntimeException(e);
        }

        return true;
    }

    public void maybeRestoreArchive()
    {
        if (Strings.isNullOrEmpty(restoreDirectories))
            return;

        for (String dir : restoreDirectories.split(DELIMITER))
        {
            File[] files = new File(dir).tryList();
            if (files == null)
            {
                throw new RuntimeException("Unable to list directory " + dir);
            }
            for (File fromFile : files)
            {
                CommitLogDescriptor fromHeader = CommitLogDescriptor.fromHeader(fromFile, DatabaseDescriptor.getEncryptionContext());
                CommitLogDescriptor fromName = CommitLogDescriptor.isValid(fromFile.name()) ? CommitLogDescriptor.fromFileName(fromFile.name()) : null;
                CommitLogDescriptor descriptor;
                if (fromHeader == null && fromName == null)
                    throw new IllegalStateException("Cannot safely construct descriptor for segment, either from its name or its header: " + fromFile.path());
                else if (fromHeader != null && fromName != null && !fromHeader.equalsIgnoringCompression(fromName))
                    throw new IllegalStateException(String.format("Cannot safely construct descriptor for segment, as name and header descriptors do not match (%s vs %s): %s", fromHeader, fromName, fromFile.path()));
                else if (fromName != null && fromHeader == null)
                    throw new IllegalStateException("Cannot safely construct descriptor for segment, as name descriptor implies a version that should contain a header descriptor, but that descriptor could not be read: " + fromFile.path());
                else if (fromHeader != null)
                    descriptor = fromHeader;
                else descriptor = fromName;

                if (descriptor.version > CommitLogDescriptor.current_version)
                    throw new IllegalStateException("Unsupported commit log version: " + descriptor.version);

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Create the directory with correct ownership: mkdir -p <dir> && chown cassandra:cassandra <dir>.
  2. Verify each restore_directories entry is an existing, readable directory (ls -ld <dir>).
  3. Fix mount/permission issues so the Cassandra process can read the directory.
  4. Remove invalid entries from restore_directories if they are not needed.

Example fix

# before
restore_directories: /mnt/old-archive
# after (directory recreated and readable)
mkdir -p /mnt/old-archive && chown cassandra:cassandra /mnt/old-archive
restore_directories: /mnt/old-archive
Defensive patterns

Strategy: validation

Validate before calling

for (String dir : restoreDirs.split(",")) {
    File d = new File(dir.trim());
    if (!d.isDirectory() || !d.canRead())
        throw new IllegalStateException("restore dir missing or unreadable: " + dir);
}

Try / catch

try { node.startup(); }
catch (RuntimeException e) {
    if (e.getMessage().startsWith("Unable to list directory"))
        log.error("Recreate/repair restore directory before restarting", e);
    throw e;
}

Prevention

When it happens

Trigger: maybeRestoreArchive() iterates restore_directories (split on delimiter); for one dir, new File(dir).tryList() returns null.

Common situations: Restore directory was deleted between configuration and startup; permissions revoked; path points to a regular file; mount not present in a container.

Related errors


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