apache/seatunnel · error · FileNotFoundException
FTP directory does not exist: ${mask(absolute)}
Error message
FTP directory does not exist: ${mask(absolute)} What it means
Thrown by SeaTunnelFTPFileSystem.list() as a FileNotFoundException when client.changeWorkingDirectory() fails for the requested directory, meaning the FTP server reports the directory does not exist (or is not accessible) at the given absolute path.
Source
Thrown at seatunnel-connectors-v2/connector-file/connector-file-ftp/src/main/java/org/apache/seatunnel/connectors/seatunnel/file/ftp/system/SeaTunnelFTPFileSystem.java:532
private static final int PAGE_SIZE = 1_000;
private final FTPClient client;
private FtpListingSession(FTPClient client) {
this.client = client;
}
@Override
public FileStatus getFileStatus(Path path) throws IOException {
return SeaTunnelFTPFileSystem.this.getFileStatus(client, path);
}
@Override
public void list(Path directory, FileStatusConsumer consumer) throws IOException {
Path workDir = new Path(client.printWorkingDirectory());
Path absolute = makeAbsolute(workDir, directory);
String previousDirectory = client.printWorkingDirectory();
if (!client.changeWorkingDirectory(absolute.toUri().getPath())) {
throw new FileNotFoundException("FTP directory does not exist: " + mask(absolute));
}
Throwable failure = null;
try {
FTPListParseEngine engine = client.initiateListParsing();
if (!FTPReply.isPositiveCompletion(client.getReplyCode())) {
throw new IOException(
"FTP LIST failed for path="
+ mask(absolute)
+ ", replyCode="
+ client.getReplyCode());
}
while (engine.hasNext()) {
FTPFile[] files = engine.getNext(PAGE_SIZE);
int skipped = emitFileStatuses(files, absolute, consumer);
if (skipped > 0) {
LOG.warn(
"Skipped "
+ skippedView on GitHub (pinned to cf67b549a7)
Solutions
- Verify the exact directory path exists with an FTP client (ls/cwd) using the same credentials
- Check path case sensitivity and leading/trailing slashes in the connector config
- Ensure the FTP user's home/permission allows entering the directory
- Pre-check with fs.exists(dir) before listing
- If the path can legitimately disappear, catch FileNotFoundException and treat as empty
Example fix
// before
FileStatus[] files = fs.listStatus(new Path("/remote/Data"));
// after
Path dir = new Path("/remote/data"); // match server case exactly
if (fs.exists(dir)) {
FileStatus[] files = fs.listStatus(dir);
} Defensive patterns
Strategy: try-catch
Validate before calling
Path dir = new Path("/remote/data");
if (!fs.exists(dir)) {
throw new IllegalArgumentException("FTP directory missing: " + dir);
} Try / catch
try {
FileStatus[] files = fs.listStatus(dir);
} catch (FileNotFoundException e) {
if (e.getMessage().contains("FTP directory does not exist")) {
// handle missing dir as empty input or fail with a clear config error
} else { throw e; }
} Prevention
- Verify directory paths (exact case, slashes) with an FTP client using the same credentials
- Pre-check fs.exists() before listing
- Remember FTP servers are case-sensitive and user home dirs change path resolution
- Catch FileNotFoundException where an absent directory is an acceptable input state
When it happens
Trigger: Listing a directory whose path does not exist on the FTP server; path typo or wrong relative path resolved against the FTP working directory; the directory was deleted between the existence check and the list; user lacks permission to enter the directory (CWD rejected).
Common situations: SeaTunnel FTP source configured with a remote path that does not exist; case-sensitivity mismatch (Linux FTP servers are case-sensitive); path containing a symlink or mount not present on the server; credentials scoped to a different home directory than expected.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Path ${file} is a directory.
- FTP LIST failed for path=${mask(absolute)}, replyCode=${clie
- File ${file} does not exist.
- Expected List type but got:
- Unknown ftp connection mode: ${mode}
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/7747d8cb0972c335.
Report an issue: GitHub.