apache/seatunnel · error · FileAlreadyExistsException

File already exists: ${file}

Error message

File already exists: ${file}

What it means

SeaTunnelFTPFileSystem.create() checks for an existing file at the target path. If the file exists and overwrite is false, it disconnects and throws org.apache.hadoop.fs.FileAlreadyExistsException('File already exists: <file>'). When overwrite is true the existing file is deleted instead.

Source

Thrown at seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java:361

            short replication,
            long blockSize,
            Progressable progress)
            throws IOException {
        final FTPClient client = connect();
        Path workDir = new Path(client.printWorkingDirectory());
        Path absolute = makeAbsolute(workDir, file);
        FileStatus status;
        try {
            status = getFileStatus(client, file);
        } catch (FileNotFoundException fnfe) {
            status = null;
        }
        if (status != null) {
            if (overwrite && !status.isDirectory()) {
                delete(client, file, false);
            } else {
                disconnect(client);
                throw new FileAlreadyExistsException("File already exists: " + file);
            }
        }

        Path parent = absolute.getParent();
        if (parent == null || !mkdirs(client, parent, FsPermission.getDirDefault())) {
            parent = (parent == null) ? new Path("/") : parent;
            disconnect(client);
            throw new IOException("create(): Mkdirs failed to create: " + parent);
        }
        client.allocate(bufferSize);
        // Change to parent directory on the server. Only then can we write to the
        // file on the server by opening up an OutputStream. As a side effect the
        // working directory on the server is changed to the parent directory of the
        // file. The FTP client connection is closed when close() is called on the
        // FSDataOutputStream.
        client.changeWorkingDirectory(parent.toUri().getPath());
        FSDataOutputStream fos =
                new FSDataOutputStream(client.storeFileStream(file.getName()), statistics) {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Set overwrite=true in create(), or enable the overwrite option in the SeaTunnel sink config if replacing is intended
  2. Delete the existing file on the FTP server or write to a unique filename (timestamp/UUID suffix)
  3. Ensure only one job writes to the same path at a time

Example fix

// before
fs.create(new Path("ftp://host/out/result.csv")); // overwrite=false default
// after
fs.create(new Path("ftp://host/out/result.csv"), true); // explicit overwrite
Defensive patterns

Strategy: validation

Validate before calling

// Java
FileSystem fs = path.getFileSystem(conf);
if (fs.exists(path) && !overwrite) {
    throw new FileAlreadyExistsException("Refusing to write existing file: " + path);
}

Try / catch

try {
    return fs.create(path, overwrite);
} catch (FileAlreadyExistsException e) {
    // decide: fail the job, or pick a new unique path
    Path unique = new Path(path.getParent(), System.currentTimeMillis() + "_" + path.getName());
    return fs.create(unique, false);
}

Prevention

When it happens

Trigger: Calling create(file, overwrite=false) (or the default create(Path) overload) where getFileStatus() finds an existing non-directory entry at the FTP server path.

Common situations: Re-running a job writing to a fixed output filename without overwrite; concurrent writers claiming the same path; leftover output from a previous failed run.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/b8895638c2998c8b. Report an issue: GitHub.