apache/flink · error · FileAlreadyExistsException

{}

Error message

{}

What it means

Thrown as FileAlreadyExistsException by LocalFileSystem.mkdirsInternal() when the target path exists but is NOT a directory (i.e. it is a regular file). The {} in the message is replaced by file.getAbsolutePath(). The exists() check intentionally precedes isDirectory() to be safe under parallel directory creation.

Source

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

     * @return <code>true</code>if the directories either already existed or have been created
     *     successfully, <code>false</code> otherwise
     * @throws IOException thrown if an error occurred while creating the directory/directories
     */
    @Override
    public boolean mkdirs(final Path f) throws IOException {
        checkNotNull(f, "path is null");
        return mkdirsInternal(pathToFile(f));
    }

    private boolean mkdirsInternal(File file) throws IOException {
        if (file.isDirectory()) {
            return true;
        } else if (file.exists() && !file.isDirectory()) {
            // Important: The 'exists()' check above must come before the 'isDirectory()' check to
            //            be safe when multiple parallel instances try to create the directory

            // exists and is not a directory -> is a regular file
            throw new FileAlreadyExistsException(file.getAbsolutePath());
        } else {
            File parent = file.getParentFile();
            return (parent == null || mkdirsInternal(parent))
                    && (file.mkdir() || file.isDirectory());
        }
    }

    @Override
    public FSDataOutputStream create(final Path filePath, final WriteMode overwrite)
            throws IOException {
        checkNotNull(filePath, "filePath");

        if (exists(filePath) && overwrite == WriteMode.NO_OVERWRITE) {
            throw new FileAlreadyExistsException("File already exists: " + filePath);
        }

        final Path parent = filePath.getParent();
        if (parent != null && !mkdirs(parent)) {

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Remove or rename the conflicting regular file at the path.
  2. Use a distinct path for the directory that does not collide with an existing file.
  3. In setup, assert the configured dir path does not point to a file before starting the job.
  4. Clear stale outputs from prior runs.

Example fix

// before (path /out/data exists as a file)
fs.mkdirs(new Path("/out/data"));

// after
new File("/out/data").delete(); // or rename
fs.mkdirs(new Path("/out/data"));
Defensive patterns

Strategy: validation

Validate before calling

void safeMkdirs(FileSystem fs, Path p) throws IOException {
    java.io.File f = new File(p.toUri());
    if (f.exists() && !f.isDirectory())
        throw new FileAlreadyExistsException("Path is a file, cannot mkdir: " + p);
    fs.mkdirs(p);
}

Try / catch

try {
    fs.mkdirs(p);
} catch (FileAlreadyExistsException e) {
    // rename/remove the conflicting file, or pick a new dir path
}

Prevention

When it happens

Trigger: Calling mkdirs(path) where path resolves to an existing regular file rather than a directory.

Common situations: Output path collides with an existing file; checkpoint dir path pointing at a file; two outputs configured to the same path with conflicting types; leftover file from a previous run blocking dir creation.

Related errors


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