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
- Create the directory with correct ownership: mkdir -p <dir> && chown cassandra:cassandra <dir>.
- Verify each restore_directories entry is an existing, readable directory (ls -ld <dir>).
- Fix mount/permission issues so the Cassandra process can read the directory.
- 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
- Health-check restore directories before node start
- Recreate restore directories as part of restore runbooks
- Avoid mounts that may detach silently
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
- Unable to create directory:
- Cannot safely construct descriptor for segment, either from
- Cannot safely construct descriptor for segment, as name and
- Cannot safely construct descriptor for segment, as name desc
- Missing required directive CommitLogSync
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/9b5af4b13c7409d3.
Report an issue: GitHub.