apache/flink · error · IOException

Failed to list contents of {directory}

Error message

Failed to list contents of {directory}

What it means

Thrown from cleanDirectoryInternal when File.listFiles() returns null while the directory still exists. listFiles() signals an I/O error or permission problem this way (null), so cleaning is impossible: the JVM cannot even enumerate the directory's children.

Source

Thrown at flink-core/src/main/java/org/apache/flink/util/FileUtils.java:354

            // exists but is file, not directory
            // either an error from the caller, or concurrently a file got created
            throw new IOException(directory + " is not a directory");
        }
        // else: does not exist, which is okay (as if deleted)
    }

    private static void cleanDirectoryInternal(File directory) throws IOException {
        if (Files.isSymbolicLink(directory.toPath())) {
            // the user directories which symbolic links point to should not be cleaned.
            return;
        }
        if (directory.isDirectory()) {
            final File[] files = directory.listFiles();

            if (files == null) {
                // directory does not exist any more or no permissions
                if (directory.exists()) {
                    throw new IOException("Failed to list contents of " + directory);
                } else {
                    throw new FileNotFoundException(directory.toString());
                }
            }

            // remove all files in the directory
            for (File file : files) {
                if (file != null) {
                    deleteFileOrDirectory(file);
                }
            }
        } else if (directory.exists()) {
            throw new IOException(directory + " is not a directory but a regular file");
        } else {
            // else does not exist at all
            throw new FileNotFoundException(directory.toString());
        }
    }

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Check permissions on the directory: it needs read+execute (Unix) or list-directory rights (Windows) for the cleaning user
  2. Fix ownership of the work dir so the Flink process owns its subtree (chown -R)
  3. If the volume is faulty (NFS/disk errors), resolve the mount/storage problem first

Example fix

# before (as wrong user)
flink clean-work-dir /opt/flink/work  # dir owned by root, mode 700

# after
sudo chown -R flink:flink /opt/flink/work
sudo chmod -R u+rwX /opt/flink/work
Defensive patterns

Strategy: validation

Validate before calling

File d = new File(dir);
if (d.isDirectory() && d.list() == null && d.exists()) {
    throw new IOException("No permission to list " + d + " - fix ownership/mode before cleanup");
}

Type guard

boolean canEnumerate(File d) { return !d.exists() || d.list() != null; }

Try / catch

catch (IOException e) during cleanup: log with the directory path and owning user; cleanup failures of caches can be non-fatal, state dirs usually fatal.

Prevention

When it happens

Trigger: FileUtils.cleanDirectory/deleteDirectory on a directory without read permission (or execute/search permission on Unix), an I/O error on the underlying disk, or a filesystem in a bad state — while an exists() check confirms the path is still present.

Common situations: Directories created by root/another user inside the Flink work dir and later cleaned by the flink user; NFS/network mounts glitching; directories with mode 000 from a misconfigured extraction; Windows ACLs denying enumeration.

Related errors


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