apache/hadoop · error · FTPException

File check failed

Error message

File check failed

What it means

Thrown by the private helper FTPFileSystem.isFile(FTPClient, Path), which shares one FTP connection across API calls to avoid reconnect overhead. It calls getFileStatus and treats FileNotFoundException as "not a file"; every other IOException (dropped control/data connection, 5xx reply, permission failure during LIST) is rethrown as FTPException("File check failed") with the original cause attached.

Source

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

    } else if (isFile(client, absolute)) {
      throw new ParentNotDirectoryException(String.format(
          "Can't make directory for path %s since it is a file.", absolute));
    }
    return created;
  }

  /**
   * 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.
   */
  private boolean isFile(FTPClient client, Path file) {
    try {
      return getFileStatus(client, file).isFile();
    } catch (FileNotFoundException e) {
      return false; // file does not exist
    } catch (IOException ioe) {
      throw new FTPException("File check failed", ioe);
    }
  }

  /*
   * Assuming that parent of both source and destination is the same. Is the
   * assumption correct or it is suppose to work like 'move' ?
   */
  @Override
  public boolean rename(Path src, Path dst) throws IOException {
    FTPClient client = connect();
    try {
      boolean success = rename(client, src, dst);
      return success;
    } finally {
      disconnect(client);
    }
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Inspect the nested cause with exception.getCause() — the Commons Net reply string shows whether it is connectivity, auth, or permission
  2. Verify reachability and credentials from the same machine with an external client (curl -u user ftp://host/) using the identical fs.ftp.* settings
  3. Keep the control connection alive between operations (shorter idle gaps, keepalive settings) so the server does not drop the session mid-conversation
  4. Confirm the directory holding the path is listable by the FTP user; grant list permission if missing
  5. Retry the operation once after reconnecting — transient network blips surface here as a wrapped error

Example fix

// before
if (fs.isFile(path)) { /* ... */ }  // FTPException("File check failed") surfaces here

// after
try {
  if (fs.isFile(path)) { /* ... */ }
} catch (FTPException e) {
  Throwable cause = e.getCause();  // original IOException from getFileStatus
  LOG.warn("FTP file check failed, cause: {}", cause, e);
  throw e;
}
Defensive patterns

Strategy: try-catch

Try / catch

catch org.apache.hadoop.fs.ftp.FTPException around the filesystem call, then branch on getCause(): FileNotFoundException means the path is gone (handle as absent); any other IOException means the FTP session itself failed — close and re-obtain the FileSystem before retrying.

Prevention

When it happens

Trigger: Invoking FTPFileSystem operations that internally probe isFile()/exists() on the shared client — e.g. rename(Path, Path) or getFileStatus — while the FTP session is broken: server killed the idle control connection, the passive data connection is blocked/refused, or the server returns an error reply while listing the path.

Common situations: vsftpd/proftpd idle_session_timeout killing the control channel between calls; firewalls/NAT dropping passive-mode data connections; wrong or expired credentials configured via fs.ftp.user.<host>/fs.ftp.password.<host>; probing paths inside directories the FTP user cannot list.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/fc6dc68fd6c63fc9. Report an issue: GitHub.