apache/hadoop · error · FileNotFoundException

Source path {src} does not exist

Error message

Source path {src} does not exist

What it means

Before issuing the FTP RNFR/RNTO pair, FTPFileSystem.rename resolves src against the server's working directory and probes existence; if the source is absent it throws java.io.FileNotFoundException("Source path <src> does not exist"). Note the message echoes the user-supplied (possibly relative) path, not the absolute path that was actually checked.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/ftp/FTPFileSystem.java:677

  /**
   * Convenience method, so that we don't open a new connection when using this
   * method from within another method. Otherwise every API invocation incurs
   * the overhead of opening/closing a TCP connection.
   * 
   * @param client
   * @param src
   * @param dst
   * @return
   * @throws IOException
   */
  @SuppressWarnings("deprecation")
  private boolean rename(FTPClient client, Path src, Path dst)
      throws IOException {
    Path workDir = new Path(client.printWorkingDirectory());
    Path absoluteSrc = makeAbsolute(workDir, src);
    Path absoluteDst = makeAbsolute(workDir, dst);
    if (!exists(client, absoluteSrc)) {
      throw new FileNotFoundException("Source path " + src + " does not exist");
    }
    if (isDirectory(absoluteDst)) {
      // destination is a directory: rename goes underneath it with the
      // source name
      absoluteDst = new Path(absoluteDst, absoluteSrc.getName());
    }
    if (exists(client, absoluteDst)) {
      throw new FileAlreadyExistsException("Destination path " + dst
          + " already exists");
    }
    URI parentSrc = absoluteSrc.getParent().toUri();
    URI parentDst = absoluteDst.getParent().toUri();
    if (isParentOf(absoluteSrc, absoluteDst)) {
      throw new IOException("Cannot rename " + absoluteSrc + " under itself"
      + " : "+ absoluteDst);
    }

    if (!parentSrc.toString().equals(parentDst.toString())) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Call fs.exists(src) immediately before rename and handle the missing case explicitly
  2. Use fully-qualified paths (fs.makeQualified(src)) so resolution against the FTP login directory cannot surprise you
  3. List the parent (fs.listStatus(src.getParent())) to confirm exact spelling and case of the entry
  4. If another process moves files, add coordination (done-marker, lease directory) so rename races cannot happen

Example fix

// before
fs.rename(src, dst);  // FileNotFoundException: Source path ... does not exist

// after
if (!fs.exists(src.makeQualified(fs))) {
  throw new FileNotFoundException("Nothing to rename at " + src + "; check spelling/case");
}
fs.rename(src, dst);
Defensive patterns

Strategy: validation

Validate before calling

// before rename
if (!fs.exists(src.makeQualified(fs))) {
  // source genuinely absent: re-list parent, alert, or skip
  LOG.warn("rename source missing: {}", src);
  return;
}
fs.rename(src, dst);

Try / catch

catch FileNotFoundException from rename and distinguish it from FTP session errors (FTPException) — only the former means the path is absent.

Prevention

When it happens

Trigger: rename(src, dst) where src does not exist on the FTP server; a relative src resolved against the FTP login directory rather than the client's expected root; the entry was deleted or moved between an exists() check and the rename; case mismatch on a case-sensitive server.

Common situations: Paths built from a different root than the FTP home directory (relative vs fully-qualified ftp:// paths); files consumed and renamed concurrently by another process; code ported from LocalFileSystem where names happened to be case-insensitive.

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/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/88ba83f9b09d65eb. Report an issue: GitHub.