apache/cassandra · error · RuntimeException
Unable to create directory:
Error message
Unable to create directory:
What it means
Thrown when parsing the restore_directories property of commitlog_archiving.properties: a configured restore directory does not exist and Cassandra's attempt to create it (tryCreateDirectory) failed. Restore needs the directory present so archived segments can be copied into it.
Solutions
- Create the restore directory manually with correct ownership: mkdir -p <dir> && chown cassandra:cassandra <dir>.
- Verify each path in restore_directories does not point to an existing regular file.
- Check the parent directory grants write permission to the Cassandra process.
- Correct the path in commitlog_archiving.properties if it is a typo.
Example fix
# before restore_directories: /nonexistent-readonly-mount/restore # after restore_directories: /var/lib/cassandra/commitlog_restore
Defensive patterns
Strategy: validation
Validate before calling
for (String dir : restoreDirs.split(",")) {
File d = new File(dir.trim());
if (d.exists() && !d.isDirectory()) throw new IllegalStateException(dir + " is a file, not a directory");
if (!d.exists() && !d.getParentFile().canWrite()) throw new IllegalStateException("cannot create " + dir);
} Try / catch
try { new CommitLogArchiver(...); }
catch (RuntimeException e) {
if (e.getMessage().startsWith("Unable to create directory")) provisionDir(e);
throw e;
} Prevention
- Pre-create restore directories with correct ownership before startup
- Validate restore_directories paths after every config change
- Avoid pointing restore_directories at mounts that may be absent (containers, NFS)
When it happens
Trigger: CommitLogArchiver.getArchiverFromProperties(), called from construct(), when a path listed in restore_directories does not exist and mkdir fails (bad permissions, path is a file, unresolvable parent path).
Common situations: Typo in restore_directories path; parent directory missing so creation fails; path points to an existing regular file; Cassandra process lacks write permission on the parent; read-only mount in containers.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- commitlog_directory must not be the same as any…
- local_system_data_file_directory must not be the same as…
- NANOSECONDS level precision is not supported.
- Unable to determine block size for commit log directory
- Unable to list directory
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/8e21f30a29748647.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/db/commitlog/CommitLogArchiver.java:140
}
@VisibleForTesting
static CommitLogArchiver getArchiverFromProperties(Properties commitlogCommands)
{
assert !commitlogCommands.isEmpty();
String archiveCommand = commitlogCommands.getProperty("archive_command");
String restoreCommand = commitlogCommands.getProperty("restore_command");
String restoreDirectories = commitlogCommands.getProperty("restore_directories");
if (restoreDirectories != null && !restoreDirectories.isEmpty())
{
for (String dir : restoreDirectories.split(DELIMITER))
{
File directory = new File(dir);
if (!directory.exists())
{
if (!directory.tryCreateDirectory())
{
throw new RuntimeException("Unable to create directory: " + dir);
}
}
}
}
String precisionPropertyValue = commitlogCommands.getProperty("precision", TimeUnit.MICROSECONDS.name());
TimeUnit precision;
try
{
precision = TimeUnit.valueOf(precisionPropertyValue);
}
catch (IllegalArgumentException ex)
{
throw new RuntimeException("Unable to parse precision of value " + precisionPropertyValue, ex);
}
if (precision == TimeUnit.NANOSECONDS)
throw new RuntimeException("NANOSECONDS level precision is not supported.");
View on GitHub (pinned to 88fd0f6a0e)