apache/seatunnel · error · IOException
SftpException wrapped (symlink resolution failed)
Error message
SftpException wrapped (symlink resolution failed)
What it means
When the LsEntry indicates the path is a symbolic link, getFileStatus() recursively resolves the link target and computes isDir/length from it; any exception in that resolution (including SftpException from the recursive stat) is wrapped in a plain IOException. So this error means 'could not resolve a symlink to determine its status'.
Solutions
- Remove or fix dangling/broken symlinks on the server (ls -l to identify them)
- Ensure link targets are reachable from the SFTP user's chroot/permissions
- Replace symlinks with real copies if the SFTP account cannot traverse targets
- Check for symlink loops (link pointing to itself or an ancestor)
- Inspect the wrapped cause to see the actual SftpException id
Example fix
// before
FileStatus st = fs.getFileStatus(new Path("/data/latest")); // symlink to deleted dir
// after
// on the server: rm /data/latest (dangling) and recreate the link or a real dir
rm /data/latest
ln -s /data/current /data/latest Defensive patterns
Strategy: validation
Validate before calling
// server-side check before the job: find /data -type l ! -exec test -e {} \; -print # list dangling symlinks Try / catch
try { st = fs.getFileStatus(p); } catch (IOException e) { if (e.getCause() != null) { /* inspect symlink SftpException */ } throw e; } Prevention
- Run symlink audits (dangling/looping links) on the SFTP root
- Ensure link targets are inside the chroot and readable
- Replace symlinks with copies where the account cannot traverse
- Log and inspect wrapped causes for SftpException ids
- Avoid symlinked output paths in automated pipelines
When it happens
Trigger: Stat'ing a path that is a symlink whose target is missing (dangling link), points outside the chroot, is cyclic, or whose parent is unreadable during the recursive getFileStatus call.
Common situations: Dangling symlinks left by previous jobs; links into directories the SFTP user cannot access; chroot setups where absolute link targets don't resolve; symlink loops.
Related errors
- Failed to get file status
- Can't make directory for path
- Can't make directory for path
- Connection pool error.
- create(): Mkdirs failed to create
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/e3ac0b03f94fe0b0.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-sftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/sftp/system/SFTPFileSystem.java:262
private FileStatus getFileStatus(
ChannelSftp channel, String fileName, SftpATTRS attr, Path parentPath)
throws IOException {
long length = attr.getSize();
boolean isDir = attr.isDir();
boolean isLink = attr.isLink();
if (isLink) {
String link = parentPath.toUri().getPath() + "/" + fileName;
try {
link = channel.realpath(link);
Path linkParent = new Path("/", link);
FileStatus fstat = getFileStatus(channel, linkParent);
isDir = fstat.isDirectory();
length = fstat.getLen();
} catch (Exception e) {
throw new IOException(e);
}
}
int blockReplication = 1;
// Using default block size since there is no way in SFTP channel to know of
// block sizes on server. The assumption could be less than ideal.
long blockSize = DEFAULT_BLOCK_SIZE;
long modTime = attr.getMTime() * 1000L; // convert to milliseconds
long accessTime = attr.getATime() * 1000L;
FsPermission permission = new FsPermission((short) attr.getPermissions());
// not be able to get the real user group name, just use the user and group
// id
String user = Integer.toString(attr.getUId());
String group = Integer.toString(attr.getGId());
Path filePath = new Path(parentPath, fileName);
return new FileStatus(
length,
isDir,View on GitHub (pinned to cf67b549a7)