apache/hadoop · error · IOException

File copy failed: {sourcePath} --> {target}

Error message

File copy failed: {sourcePath} --> {target}

What it means

Top-level wrapper for a single-file copy failure inside the DistCp mapper: RetriableFileCopyCommand.execute() threw after exhausting its internal retries, and CopyMapper.rethrows with the source and target paths. The underlying reason (source read error, target write error, tmp-file promote failure, length/checksum verification, interruption) is in the exception's cause chain.

Source

Thrown at hadoop-tools/hadoop-distcp/src/main/java/org/apache/hadoop/tools/mapred/CopyMapper.java:281

    String attributeString = context.getConfiguration().get(
            DistCpOptionSwitch.PRESERVE_STATUS.getConfigLabel());
    return DistCpUtils.unpackAttributes(attributeString);
  }

  @SuppressWarnings("checkstyle:parameternumber")
  private void copyFileWithRetry(String description,
      CopyListingFileStatus sourceFileStatus, Path target,
      FileStatus targrtFileStatus, Context context, FileAction action,
      EnumSet<FileAttribute> fileAttributes, FileStatus sourceStatus)
      throws IOException, InterruptedException {
    long bytesCopied;
    try {
      bytesCopied = (Long) new RetriableFileCopyCommand(skipCrc, description,
          action, directWrite).execute(sourceFileStatus, target, context,
              fileAttributes, sourceStatus);
    } catch (Exception e) {
      context.setStatus("Copy Failure: " + sourceFileStatus.getPath());
      throw new IOException("File copy failed: " + sourceFileStatus.getPath() +
          " --> " + target, e);
    }
    incrementCounter(context, Counter.BYTESEXPECTED, sourceFileStatus.getLen());
    incrementCounter(context, Counter.BYTESCOPIED, bytesCopied);
    incrementCounter(context, Counter.COPY, 1);
    totalBytesCopied += bytesCopied;

    if (verboseLog) {
      context.write(null,
          new Text("FILE_COPIED: source=" + sourceFileStatus.getPath() + ","
          + " size=" + sourceFileStatus.getLen() + " --> "
          + "target=" + target + ", size=" + (targrtFileStatus == null ?
              0 : targrtFileStatus.getLen())));
    }
  }

  private void createTargetDirsWithRetry(String description, Path target,
      Context context, FileStatus sourceStatus, FileSystem sourceFS) throws IOException {

View on GitHub (pinned to 2add963021)

Solutions

  1. Walk the cause chain (repeated e.getCause()) and the mapper log for the failing file to find the true error
  2. Fix the root cause: restore source readability, free quota/space, remove conflicting target files, stop concurrent writers
  3. Verify source integrity with 'hdfs fsck <sourcePath> -files -blocks' if block corruption is suspected
  4. Re-run with -update: completed files are skipped and only failures are retried
Defensive patterns

Strategy: retry

Validate before calling

// probe that the source is openable before the job
try (FSDataInputStream ignored = sourceFS.open(sourcePath)) {
  // readable
}

Try / catch

catch (IOException e) {  // 'File copy failed: src --> target'
  Throwable root = e;
  while (root.getCause() != null) root = root.getCause();
  // root is the real failure: read error, write error, promote failure, checksum...
  LOG.error("copy of {} failed: {}", sourcePath, root, e);
}

Prevention

When it happens

Trigger: Source file unreadable or deleted mid-job (CopyReadException), target not writable or disk/quota full, promoteTmpToTarget() failing on a conflicting target file, post-copy length or checksum verification failing, or the task being interrupted.

Common situations: Source permissions changed or files deleted while the job ran; target quota exhausted; two distcp jobs writing the same file; flaky DataNodes/NameNode outlasting the retry budget; corrupted source blocks.

Related errors


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