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

  1. Choose a different directory path that does not collide with an existing file
  2. Delete the conflicting file first if it is safe to remove
  3. Verify the path with fs.getFileStatus(path).isFile()/isDirectory() before mkdirs
  4. 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

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


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