apache/seatunnel · error · IOException
SftpException wrapped (pwd failed while renaming)
Error message
SftpException wrapped (pwd failed while renaming)
What it means
rename() resolves the working directory via channel.pwd() before making src/dst absolute; if pwd throws, the SftpException is wrapped in an IOException. This happens before any existence checks, so it indicates the channel/server was already in a bad state when the rename started.
Source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-sftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sftp/system/SFTPFileSystem.java:439
}
ArrayList<FileStatus> fileStats = new ArrayList<FileStatus>();
for (int i = 0; i < sftpFiles.size(); i++) {
LsEntry entry = sftpFiles.get(i);
String fname = entry.getFilename();
// skip current and parent directory, ie. "." and ".."
if (!".".equalsIgnoreCase(fname) && !"..".equalsIgnoreCase(fname)) {
fileStats.add(getFileStatus(client, entry, absolute));
}
}
return fileStats.toArray(new FileStatus[fileStats.size()]);
}
private boolean rename(ChannelSftp channel, Path src, Path dst) throws IOException {
Path workDir;
try {
workDir = new Path(channel.pwd());
} catch (SftpException e) {
throw new IOException(e);
}
Path absoluteSrc = makeAbsolute(workDir, src);
Path absoluteDst = makeAbsolute(workDir, dst);
if (!exists(channel, absoluteSrc)) {
throw new IOException(String.format(E_SPATH_NOTEXIST, src));
}
if (exists(channel, absoluteDst)) {
throw new IOException(String.format(E_DPATH_EXIST, dst));
}
boolean renamed = true;
try {
final String previousCwd = channel.pwd();
channel.cd("/");
channel.rename(src.toUri().getPath(), dst.toUri().getPath());
channel.cd(previousCwd);
} catch (SftpException e) {
renamed = false;View on GitHub (pinned to cf67b549a7)
Solutions
- Reconnect and retry the rename
- Enable SSH keep-alive (ServerAliveInterval) to keep the session alive across job phases
- Check the wrapped SftpException id to diagnose server vs transport failure
- Ensure channels are returned to the pool and revalidated before reuse
Defensive patterns
Strategy: retry
Validate before calling
try {
fs.exists(new Path("/")); // channel health probe
} catch (IOException e) {
reconnect();
} Try / catch
try {
fs.rename(src, dst);
} catch (IOException e) {
if (e.getCause() instanceof SftpException) { reconnect(); /* retry rename */ }
throw e;
} Prevention
- Keep the session alive during long write phases (keep-alive)
- Revalidate the channel right before commit-time renames
- Make renames retry-safe and idempotent
When it happens
Trigger: fs.rename(src, dst) (commit phase, file-move steps) when the SFTP session is closed, authentication expired, or the server fails the pwd request.
Common situations: Session idle timeout before the job's commit/rename step; server restart between write and rename; stale pooled channel; firewall dropping long-lived SSH control connection.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- SftpException wrapped (pwd failed while resolving file statu
- SftpException wrapped (pwd failed while creating directory)
- SftpException wrapped (pwd failed while deleting)
- SftpException wrapped (pwd failed while listing status)
- Source path %s does not exist
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/7f13415c6a6c5e95.
Report an issue: GitHub.