apache/hadoop · error · IOException

Cannot find target file - {trg}

Error message

Cannot find target file - {trg}

What it means

In RouterAsyncClientProtocol.concat, the Router first resolves the target file's actual remote location (getFileRemoteLocation(trg)). A null targetDestination means no subcluster returned a file status for the target path, so concat cannot proceed and IOException('Cannot find target file - <trg>') is thrown. concat requires the target to exist because its nameservice determines where the concatenated blocks must live.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/async/RouterAsyncClientProtocol.java:320

              + " allowed. The number of remote locations for both source and"
              + " target should be same.");
        }
        rpcClient.invokeConcurrent(locs, method);
      } else {
        rpcClient.invokeSequential(locs, method, null, null);
      }
    });
  }

  @Override
  public void concat(String trg, String[] src) throws IOException {
    rpcServer.checkOperation(NameNode.OperationCategory.WRITE);

    // Concat only effects when all files in the same namespace.
    getFileRemoteLocation(trg);
    asyncApply((AsyncApplyFunction<RemoteLocation, Object>) targetDestination -> {
      if (targetDestination == null) {
        throw new IOException("Cannot find target file - " + trg);
      }
      String targetNameService = targetDestination.getNameserviceId();
      String[] sourceDestinations = new String[src.length];
      int[] index = new int[1];
      asyncForEach(Arrays.stream(src).iterator(), (forEachRun, sourceFile) -> {
        getFileRemoteLocation(sourceFile);
        asyncApply((ApplyFunction<RemoteLocation, Object>) srcLocation -> {
          if (srcLocation == null) {
            throw new IOException("Cannot find source file - " + sourceFile);
          }
          sourceDestinations[index[0]++] = srcLocation.getDest();
          if (!targetNameService.equals(srcLocation.getNameserviceId())) {
            throw new IOException("Cannot concatenate source file " + sourceFile
                + " because it is located in a different namespace" + " with nameservice "
                + srcLocation.getNameserviceId() + " from the target file with nameservice "
                + targetNameService);
          }
          return null;

View on GitHub (pinned to 2add963021)

Solutions

  1. Verify the target exists via the Router (hdfs dfs -ls) and re-issue concat with the correct path
  2. If the file exists in a subcluster but not through the Router, fix the mount entry for that path (hdfs dfsrouteradmin -ls / -add) and refresh
  3. Guard against races by re-checking existence immediately before concat in job logic
Defensive patterns

Strategy: validation

Validate before calling

// Verify target exists via the Router before concat:
if (dfs.getClient().getNamenode().getFileInfo(trg) == null) {
  // fail fast with a clear error instead of calling concat
}

Try / catch

catch (IOException e) {
  if (e.getMessage().startsWith("Cannot find target file - ")) {
    // refresh path or fix mount entry; do not retry blindly
  }
}

Prevention

When it happens

Trigger: WebHDFS/RPC concat where the target file does not exist in any namespace; target was deleted concurrently; mount table maps the target path to a different namespace than where it actually resides.

Common situations: Stale paths after file migration between subclusters; races between a listing and concat in job commit logic; mount table edits that re-route the target path.

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/39d163d55d096d96. Report an issue: GitHub.