apache/cassandra · warning

Cannot delete the directory

Error message

Cannot delete the directory {} as it is not empty. (Content: {})

What it means

After a recursive move, FileUtils.deleteDirectoryIfEmpty tries to delete the now-empty source directory; if the OS reports DirectoryNotEmptyException it logs a warning listing the directory's contents and leaves it in place.

Solutions

  1. Investigate what is still writing to the source directory and stop it before moving
  2. Re-run the move or manually delete the directory once it is genuinely empty
  3. Check for orphaned files (e.g. partial sstables) left behind and clean them with the appropriate tooling
  4. Avoid moving live data directories; quiesce writes first

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

try (Stream<Path> remaining = Files.list(sourceDir)) {
    if (remaining.findAny().isPresent()) {
        // directory still in use; abort or defer the move
    }
}

Type guard

boolean isEmptyDir(Path p) throws IOException { try (Stream<Path> s = Files.list(p)) { return s.findAny().isEmpty(); } }

Try / catch

try {
    FileUtils.moveRecursively(source, target);
} catch (DirectoryNotEmptyException e) {
    // stop writers to source, clean leftovers, delete manually
}

Prevention

When it happens

Trigger: moveRecursively finished moving files but new files appeared in the source directory mid-move (concurrent writers), so the directory is no longer empty at deletion time.

Common situations: Concurrent compaction or flush writing new sstables into the source directory while it is being moved; interrupted prior moves leaving stray files.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/io/util/FileUtils.java:740

     *
     * @param path the path to the directory
     */
    public static void deleteDirectoryIfEmpty(Path path) throws IOException
    {
        Preconditions.checkArgument(Files.isDirectory(path), String.format("%s is not a directory", path));

        try
        {
            logger.info("Deleting directory {}", path);
            Files.delete(path);
        }
        catch (DirectoryNotEmptyException e)
        {
            try (Stream<Path> paths = Files.list(path))
            {
                String content = paths.map(p -> p.getFileName().toString()).collect(Collectors.joining(", "));

                logger.warn("Cannot delete the directory {} as it is not empty. (Content: {})", path, content);
            }
        }
    }

    public static boolean isDirectIOSupported(File file)
    {
        File testFile = null;
        try
        {
            File dir = file.isDirectory() ? file : file.parent();
            testFile = createTempFile("direct-io-test", ".tmp", dir);

            // Direct IO requires knowing the block size for buffer alignment
            if (blockSize(testFile) <= 0)
                return false;

            try (FileChannel channel = FileChannel.open(testFile.toPath(),
                                                        StandardOpenOption.READ,

View on GitHub (pinned to 88fd0f6a0e)