apache/flink · error · IOException

Directory {} does not exist or an I/O error occurred

Error message

Directory {} does not exist or an I/O error occurred

What it means

Thrown by LocalFileSystem.delete() when File.listFiles() returns null on a directory entry. listFiles() returns null when the path doesn't exist or an I/O error occurred (e.g. permission denied on listing). The non-recursive delete path detects this and surfaces it.

Source

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

        }
        results = new FileStatus[names.length];
        for (int i = 0; i < names.length; i++) {
            results[i] = getFileStatus(new Path(f, names[i]));
        }

        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

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. If intentional recursive removal, call delete(path, recursive=true) which takes a different code path.
  2. Check and fix directory permissions so the Flink user can list it.
  3. Guard against races by catching IOException and re-checking existence, or retry once.
  4. Ensure no other process concurrently deletes the directory during the operation.

Example fix

// before
fs.delete(dirPath, false);

// after (if recursive intended)
fs.delete(dirPath, true);
Defensive patterns

Strategy: try-catch

Try / catch

try {
    fs.delete(p, false);
} catch (IOException e) {
    if (e.getMessage().contains("does not exist or an I/O error occurred")) {
        if (!fs.exists(p)) return; // already gone
        // else retry with recursive or fix perms
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling delete(path, recursive=false) on a directory that vanished between isDirectory() and listFiles(), or whose contents cannot be enumerated due to permissions/I/O.

Common situations: Concurrent deletion by another process; permission denied on directory listing; filesystem errors (NFS hiccup, disk failure); race between check and use.

Related errors


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