apache/seatunnel · error · FileNotFoundException

File does not exist.

Error message

File %s does not exist.

What it means

getFileStatus() lists the parent directory with client.ls(parentPath). If the ls call throws an SftpException, the code converts it into a FileNotFoundException("File %s does not exist."). Note this conflates real errors (permission denied on the parent dir, path is actually a file) with genuine non-existence, because any SftpException from ls becomes 'file does not exist'.

Solutions

  1. Verify the parent directory exists and is readable/traversable by the SFTP user (ls it manually)
  2. Check the exact path spelling and working directory (relative vs absolute path)
  3. Grant the SFTP account read+execute on all ancestor directories
  4. Distinguish the wrapped cause: if the original SftpException id is 3 (permission denied), fix permissions rather than assuming the file is missing
  5. Use an absolute path to avoid surprises from a changed working directory

Example fix

// before
FileStatus st = fs.getFileStatus(new Path("/data/out/file.txt")); // parent /data/out unreadable -> FNFE
// after
if (!fs.exists(new Path("/data/out"))) {
    fs.mkdirs(new Path("/data/out")); // ensure parent exists & is accessible
}
FileStatus st = fs.getFileStatus(new Path("/data/out/file.txt"));
Defensive patterns

Strategy: validation

Validate before calling

Path parent = path.getParent(); if (!fs.exists(parent)) throw new IllegalStateException("Parent missing: " + parent); // also verify with manual sftp ls that the account can read it

Try / catch

try { st = fs.getFileStatus(path); } catch (FileNotFoundException e) { /* treat as absent or fix parent perms */ }

Prevention

When it happens

Trigger: ls() on the parent directory fails with any SftpException — e.g. permission denied (id 3), no such file (id 2) when the parent itself is missing, or the path points at a regular file so its 'parent listing' lookup behaves oddly.

Common situations: Parent directory unreadable by the SFTP user (missing +x/+r); typo in path so the parent dir is absent; checking status of a file inside a directory the account cannot traverse; chrooted users with restricted listings.

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


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/21b57b86aaa5f099. 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:221

            boolean isDir = true;
            int blockReplication = 1;
            long blockSize = DEFAULT_BLOCK_SIZE; // Block Size not known.
            long modTime = -1; // Modification time of root directory not known.
            Path root = new Path("/");
            return new FileStatus(
                    length,
                    isDir,
                    blockReplication,
                    blockSize,
                    modTime,
                    root.makeQualified(this.getUri(), this.getWorkingDirectory()));
        }
        String pathName = parentPath.toUri().getPath();
        Vector<LsEntry> sftpFiles;
        try {
            sftpFiles = (Vector<LsEntry>) client.ls(pathName);
        } catch (SftpException e) {
            throw new FileNotFoundException(String.format(E_FILE_NOTFOUND, file));
        }
        if (sftpFiles != null) {
            for (LsEntry sftpFile : sftpFiles) {
                if (sftpFile.getFilename().equals(file.getName())) {
                    // file found in directory
                    fileStat = getFileStatus(client, sftpFile, parentPath);
                    break;
                }
            }
            if (fileStat == null) {
                throw new FileNotFoundException(String.format(E_FILE_NOTFOUND, file));
            }
        } else {
            throw new FileNotFoundException(String.format(E_FILE_NOTFOUND, file));
        }
        return fileStat;
    }

View on GitHub (pinned to cf67b549a7)