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
- Ensure the parent directory exists (create parents first or fs.mkdirs the full hierarchy in order)
- Check FTP reply code/string in the error: 550 → permission/not-found, 530 → login issue
- Verify the FTP user's home directory and permissions allow entering the parent path
- Use paths relative to the FTP user's root instead of server-absolute paths
- 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
- Create parent directories hierarchically before creating deep paths
- Prefer paths relative to the FTP user's root over server-absolute paths
- Confirm the FTP user can CWD into the parent (permissions, home-dir scoping)
- Test directory creation manually with the same credentials before production
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
- create(): Mkdirs failed to create: ${parent}
- Unable to create file: ${file}, Aborting
- Can't make directory for path %s since it is a file.
- Couldn't create directory %s.
- Failed to list tables in dataset:
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/84a16bdf8b17963d.
Report an issue: GitHub.