apache/seatunnel · error · IOException
Can't make directory for path "%s" under "%s".
Error message
Can't make directory for path "%s" under "%s".
What it means
mkdirs() attempts to create the leaf directory by cd'ing to the parent and calling client.mkdir(pathName). Any SftpException from that sequence is converted to IOException("Can't make directory for path \"%s\" under \"%s\".") — the SFTP server refused the MKDIR, typically because of permissions or because the entry already exists.
Source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-sftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sftp/system/SFTPFileSystem.java:324
} catch (SftpException e) {
throw new IOException(e);
}
Path absolute = makeAbsolute(workDir, file);
String pathName = absolute.getName();
if (!exists(client, absolute)) {
Path parent = absolute.getParent();
created = parent == null || mkdirs(client, parent, FsPermission.getDefault());
if (created) {
String parentDir = parent.toUri().getPath();
boolean succeeded = true;
try {
final String previousCwd = client.pwd();
client.cd(parentDir);
LOG.debug("Creating directory " + pathName);
client.mkdir(pathName);
client.cd(previousCwd);
} catch (SftpException e) {
throw new IOException(String.format(E_MAKE_DIR_FORPATH, pathName, parentDir));
}
created = created & succeeded;
}
} else if (isFile(client, absolute)) {
throw new IOException(String.format(E_DIR_CREATE_FROMFILE, absolute));
} else {
LOG.debug("Skipping creation of existing directory " + file);
}
if (!created) {
LOG.debug("Failed to create " + file);
}
return created;
}
private boolean isFile(ChannelSftp channel, Path file) throws IOException {
try {
return !getFileStatus(channel, file).isDirectory();
} catch (FileNotFoundException e) {View on GitHub (pinned to cf67b549a7)
Solutions
- Grant the SFTP user write permission on the parent directory
- Check the server for quota or disk-space limits
- Handle 'already exists' benignly: verify with exists() before/after and ignore id-4 conflicts if the dir is present
- Ensure no concurrent jobs race to create the same path, or serialize creation
- Check the wrapped SftpException id in server/client logs for the precise cause
Example fix
// before
fs.mkdirs(new Path("/data/out")); // permission denied on /data
// after
// grant write on server: chown sftpuser /data && chmod u+w /data
chmod u+w /data
fs.mkdirs(new Path("/data/out")); Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: ensure parent writable by the account; server-side: sudo -u sftpuser test -w /data/parent Path parent = path.getParent(); if (!fs.exists(parent)) fs.mkdirs(parent);
Try / catch
try { fs.mkdirs(p); } catch (IOException e) { if (fs.exists(p) && fs.getFileStatus(p).isDirectory()) { /* benign race: already created */ } else { throw e; } } Prevention
- Grant write permission on parent dirs
- Check server quota/disk space
- Serialize concurrent jobs creating the same dir
- Inspect SftpException id 3 (perm) vs 4 (failure)
- Pre-create directory trees during setup
When it happens
Trigger: client.mkdir() fails with permission denied (SFTP id 3), failure (id 4), or the directory already exists on servers that error instead of succeeding; also cd() to the parent failing mid-sequence.
Common situations: SFTP user lacks write permission on the parent directory; quota/disk-full on the server; concurrent jobs creating the same directory; read-only mounts on the server side.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- SftpException wrapped (pwd failed while creating directory)
- Can't make directory for path %s since it is a file.
- create(): Mkdirs failed to create: %s
- create(): Mkdirs failed to create: ${parent}
- Can't make directory for path %s since it is a file.
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/412895c58bbed9f4.
Report an issue: GitHub.