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
- Set overwrite=true in create(), or enable the overwrite option in the SeaTunnel sink config if replacing is intended
- Delete the existing file on the FTP server or write to a unique filename (timestamp/UUID suffix)
- 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
- Pass overwrite=true explicitly when replacement is intended
- Generate unique output names (timestamp/partition suffix) for idempotent reruns
- Clean up stale outputs from failed runs before resubmitting
- Ensure a single writer owns each output path
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
- Path ${file} is a directory.
- Invalid host specified
- Invalid user/password specified
- Unable to open file: ${file}, Aborting
- create(): Mkdirs failed to create: ${parent}
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/b8895638c2998c8b.
Report an issue: GitHub.