apache/seatunnel · error · IOException

Failed to change working directory to %s, FTP reply code: %d

Error message

Failed to change working directory to %s, FTP reply code: %d, reply string: %s

What it means

Thrown when creating a directory on the FTP server: the client could not change its working directory (CWD) to the intended parent directory before issuing MKD, so the create is aborted. The message includes the parent path, FTP reply code, and reply string for diagnosis.

Source

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

                        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)) {
            throw new IOException(
                    String.format(
                            "Failed to change working directory to %s, FTP reply code: %d, reply string: %s",
                            parentDir, client.getReplyCode(), client.getReplyString()));
        }
        // Create directory
        boolean created = client.makeDirectory(pathName);
        if (!created) {
            // Double check if directory was actually created (some FTP servers don't return true)
            if (!exists(client, absolute)) {
                throw new IOException(
                        String.format(
                                "Failed to create directory %s in %s, FTP reply code: %d, reply string: %s",
                                pathName,
                                parentDir,
                                client.getReplyCode(),
                                client.getReplyString()));
            }
        }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Ensure the parent directory exists (create parents first or fs.mkdirs the full hierarchy in order)
  2. Check FTP reply code/string in the error: 550 → permission/not-found, 530 → login issue
  3. Verify the FTP user's home directory and permissions allow entering the parent path
  4. Use paths relative to the FTP user's root instead of server-absolute paths
  5. Test CWD to the parent manually with the same credentials

Example fix

// before
fs.mkdirs(new Path("/data/output/2026/09")); // /data/output missing
// after
for (Path p : Arrays.asList(new Path("/data/output/2026"), new Path("/data/output/2026/09"))) {
    if (!fs.exists(p)) {
        fs.mkdirs(p);
    }
}
Defensive patterns

Strategy: validation

Validate before calling

Path parent = path.getParent();
if (!fs.exists(parent)) {
    fs.mkdirs(parent); // create parents before the CWD-based create path
}

Try / catch

try {
    fs.mkdirs(dir);
} catch (IOException e) {
    if (e.getMessage().startsWith("Failed to change working directory")) {
        // parse reply code from message: 550 → permission/not-found; fix parent path or perms
    } else { throw e; }
}

Prevention

When it happens

Trigger: fs.mkdirs(path) where the parent directory does not exist on the server, the user lacks execute/enter permission on it, or the CWD command is rejected by the server (path invalid, permission denied, connection issue).

Common situations: Creating deep nested output paths whose parent does not exist yet on the FTP server; FTP user confined to a home directory so absolute parents like /data are not enterable; typo'd base path in connector config; permission-restricted directories.

Understand the failure class

Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.

Related errors


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