apache/hadoop · error · UnsupportedOperationException

Tracking file movement in basic FileSystem is not supported

Error message

Tracking file movement in basic FileSystem is not supported

What it means

Thrown by RawLocalFileSystem.createPathHandle when the caller requests a location-tolerant handle via Options.HandleOpt.moved(true) (or any Location option that allows change). The local FileSystem builds its handle purely from the path string plus mtime, so it cannot track a file that is renamed or moved; only content-stable (moved(false)) handles are supported. Requesting a capability the basic FileSystem lacks is rejected with UnsupportedOperationException.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/RawLocalFileSystem.java:1246

   *            {@link PathHandle} reference.
   */
  protected PathHandle createPathHandle(FileStatus stat,
      Options.HandleOpt... opts) {
    if (stat.isDirectory() || stat.isSymlink()) {
      throw new IllegalArgumentException("PathHandle only available for files");
    }
    String authority = stat.getPath().toUri().getAuthority();
    if (authority != null && !authority.equals("file://")) {
      throw new IllegalArgumentException("Wrong FileSystem: " + stat.getPath());
    }
    Options.HandleOpt.Data data =
        Options.HandleOpt.getOpt(Options.HandleOpt.Data.class, opts)
            .orElse(Options.HandleOpt.changed(false));
    Options.HandleOpt.Location loc =
        Options.HandleOpt.getOpt(Options.HandleOpt.Location.class, opts)
            .orElse(Options.HandleOpt.moved(false));
    if (loc.allowChange()) {
      throw new UnsupportedOperationException("Tracking file movement in " +
          "basic FileSystem is not supported");
    }
    final Path p = stat.getPath();
    final Optional<Long> mtime = !data.allowChange()
        ? Optional.of(stat.getModificationTime())
        : Optional.empty();
    return new LocalFileSystemPathHandle(p.toString(), mtime);
  }

  @Override
  public boolean supportsSymlinks() {
    return true;
  }

  @SuppressWarnings("deprecation")
  @Override
  public void createSymlink(Path target, Path link, boolean createParent)
      throws IOException {

View on GitHub (pinned to 2add963021)

Solutions

  1. Use the default location constraint: call getPathHandle(stat) or pass Options.HandleOpt.moved(false)
  2. Branch on filesystem capabilities: request moved(true) only for filesystems whose handles support it (HDFS)
  3. Catch UnsupportedOperationException and fall back to opening the file by path when running on local FS

Example fix

// before
PathHandle h = fs.getPathHandle(stat, Options.HandleOpt.moved(true));

// after
PathHandle h = fs.getPathHandle(stat, Options.HandleOpt.moved(false));
Defensive patterns

Strategy: validation

Validate before calling

Options.HandleOpt[] opts = (fs instanceof LocalFileSystem || fs instanceof RawLocalFileSystem)
    ? new Options.HandleOpt[]{ Options.HandleOpt.moved(false) }
    : new Options.HandleOpt[]{ Options.HandleOpt.moved(true) };
PathHandle h = fs.getPathHandle(stat, opts);

Try / catch

try {
  h = fs.getPathHandle(stat, Options.HandleOpt.moved(true));
} catch (UnsupportedOperationException e) {
  // basic FS cannot track movement; degrade to path+mtime handle
  h = fs.getPathHandle(stat, Options.HandleOpt.moved(false));
}

Prevention

When it happens

Trigger: fs.getPathHandle(stat, Options.HandleOpt.moved(true)) on RawLocalFileSystem/LocalFileSystem; generic client code that always requests the most permissive opts (changed(false), moved(true)) and runs against file:// URIs.

Common situations: Porting an HDFS-based application (where HdfsPathHandle tolerates movement) to local FS for testing or edge-node execution; shared library code that hardcodes HandleOpts across filesystems.

Related errors


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