apache/flink · error · IOException

Directory {} is not empty

Error message

Directory {} is not empty

What it means

Thrown by LocalFileSystem.delete() in non-recursive mode when the target directory exists and contains files (listFiles().length != 0). It prevents accidental silent non-deletion of a non-empty directory.

Source

Thrown at flink-core/src/main/java/org/apache/flink/core/fs/local/LocalFileSystem.java:186

        return results;
    }

    @Override
    public boolean delete(final Path f, final boolean recursive) throws IOException {

        final File file = pathToFile(f);
        if (file.isFile()) {
            return file.delete();
        } else if ((!recursive) && file.isDirectory()) {
            File[] containedFiles = file.listFiles();
            if (containedFiles == null) {
                throw new IOException(
                        "Directory "
                                + file.toString()
                                + " does not exist or an I/O error occurred");
            } else if (containedFiles.length != 0) {
                throw new IOException("Directory " + file.toString() + " is not empty");
            }
        }

        return delete(file);
    }

    /**
     * Deletes the given file or directory.
     *
     * @param f the file to be deleted
     * @return <code>true</code> if all files were deleted successfully, <code>false</code>
     *     otherwise
     * @throws IOException thrown if an error occurred while deleting the files/directories
     */
    private boolean delete(final File f) throws IOException {

        if (f.isDirectory()) {
            final File[] files = f.listFiles();

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Pass recursive=true if you intend to delete the whole tree: `fs.delete(path, true)`.
  2. If non-recursive is intentional, empty the directory first or pick an empty target.
  3. Configure your sink/output to use a fresh directory or set overwrite mode.

Example fix

// before
fs.delete(outputDir, false); // throws if non-empty

// after
fs.delete(outputDir, true);
Defensive patterns

Strategy: validation

Validate before calling

void deleteDir(FileSystem fs, Path p, boolean recursive) throws IOException {
    if (!recursive && fs.getFileStatus(p).isDir()) {
        // caller must confirm emptiness or choose recursive
    }
    fs.delete(p, recursive);
}

Try / catch

try {
    fs.delete(p, false);
} catch (IOException e) {
    if (e.getMessage().endsWith("is not empty")) fs.delete(p, true);
    else throw e;
}

Prevention

When it happens

Trigger: Calling delete(path, recursive=false) on a directory that contains one or more entries.

Common situations: Forgetting to set recursive=true when clearing an output directory; checkpoint cleanup over a partially-populated dir; output dir reuse with leftover data.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/5767edd57e7d7e21. Report an issue: GitHub.