apache/seatunnel · error · ParentNotDirectoryException
Can't make directory for path %s since it is a file.
Error message
Can't make directory for path %s since it is a file.
What it means
Thrown by SeaTunnelFTPFileSystem's internal mkdir path as a ParentNotDirectoryException: the path passed to mkdir already exists but is a regular file, so a directory of that name cannot be created there.
Source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java:729
return success;
} finally {
disconnect(client);
}
}
/**
* Convenience method, so that we don't open a new connection when using this method from within
* another method. Otherwise every API invocation incurs the overhead of opening/closing a TCP
* connection.
*/
private boolean mkdirs(FTPClient client, Path file, FsPermission permission)
throws IOException {
Path workDir = new Path(client.printWorkingDirectory());
Path absolute = makeAbsolute(workDir, file);
// If directory already exists, return true
if (exists(client, absolute)) {
if (isFile(client, absolute)) {
throw new ParentNotDirectoryException(
String.format(
"Can't make directory for path %s since it is a file.", absolute));
}
return true;
}
// Create parent directories if they don't exist
Path parent = absolute.getParent();
if (parent != null && !exists(client, parent)) {
mkdirs(client, parent, FsPermission.getDirDefault());
}
// Create the directory
String pathName = absolute.getName();
String parentDir = parent != null ? parent.toUri().getPath() : "/";
// Change to parent directory
if (!client.changeWorkingDirectory(parentDir)) {View on GitHub (pinned to cf67b549a7)
Solutions
- Choose a different directory path that does not collide with an existing file
- Delete the conflicting file first if it is safe to remove
- Verify the path with fs.getFileStatus(path).isFile()/isDirectory() before mkdirs
- Align directory naming conventions (e.g. always append a directory name, never rely on slash handling)
Example fix
// before
fs.mkdirs(new Path("/data/2026-09-10")); // exists as a file
// after
Path dir = new Path("/data/2026-09-10");
if (fs.exists(dir) && fs.getFileStatus(dir).isFile()) {
fs.delete(dir, false); // remove conflicting file, then create dir
}
fs.mkdirs(dir); Defensive patterns
Strategy: validation
Validate before calling
Path dir = new Path("/data/2026-09-10");
if (fs.exists(dir) && fs.getFileStatus(dir).isFile()) {
throw new IllegalStateException("Path exists as a file: " + dir);
} Try / catch
try {
fs.mkdirs(dir);
} catch (IOException e) {
if (e.getMessage().contains("since it is a file")) {
// pick a new path or delete the conflicting file deliberately
} else { throw e; }
} Prevention
- Check exists()+isFile() before mkdirs on reused paths
- Adopt a consistent layout where directories and files never share a path prefix collision
- Delete or archive old run outputs before reusing directory names
- Use unique run-id based directory names to avoid collisions
When it happens
Trigger: Calling fs.mkdirs(path) (or a code path that auto-creates directories) where an existing file occupies the exact same path — e.g. a previous run wrote /data/part-0 as a file and config now uses /data/part-0 as a directory.
Common situations: Output path configuration colliding with an existing file from a prior run; missing trailing-slash conventions causing a directory path to equal a file path; reused bucket/directory layout changed between job versions.
Related errors
- create(): Mkdirs failed to create: ${parent}
- Directory: ${file} is not empty.
- Failed to change working directory to %s, FTP reply code: %d
- Unknown ftp connection mode: ${mode}
- Invalid host specified
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/8471f9587f5776cf.
Report an issue: GitHub.