apache/hadoop · error · IOException

Failed to promote tmp-file:{tmpTarget} to: {target}

Error message

Failed to promote tmp-file:{tmpTarget} to: {target}

What it means

RetriableFileCopyCommand writes each file to a temp file (.distcp.tmp.<taskAttemptId> under the work path) and then promotes it via promoteTmpToTarget(). The promote fails if the target exists and delete(target, false) fails, if the target's parent is missing and mkdirs fails, or if the final rename fails. The copied bytes remain in the tmp file named in the message.

Source

Thrown at hadoop-tools/hadoop-distcp/src/main/java/org/apache/hadoop/tools/mapred/RetriableFileCopyCommand.java:259

      }
      outStream = new BufferedOutputStream(out);
    } else {
      outStream = new BufferedOutputStream(targetFS.append(targetPath,
          copyBufferSize));
    }
    return copyBytes(source, sourceOffset, outStream, copyBufferSize,
        context);
  }

  //If target file exists and unable to delete target - fail
  //If target doesn't exist and unable to create parent folder - fail
  //If target is successfully deleted and parent exists, if rename fails - fail
  private void promoteTmpToTarget(Path tmpTarget, Path target, FileSystem fs)
                                  throws IOException {
    if ((fs.exists(target) && !fs.delete(target, false))
        || (!fs.exists(target.getParent()) && !fs.mkdirs(target.getParent()))
        || !fs.rename(tmpTarget, target)) {
      throw new IOException("Failed to promote tmp-file:" + tmpTarget
                              + " to: " + target);
    }
  }

  private Path getTempFile(Path target, Mapper.Context context) {
    Path targetWorkPath = new Path(context.getConfiguration().
        get(DistCpConstants.CONF_LABEL_TARGET_WORK_PATH));

    Path root = target.equals(targetWorkPath) ? targetWorkPath.getParent()
        : targetWorkPath;
    Path tempFile = new Path(root, ".distcp.tmp." +
        context.getTaskAttemptID().toString() +
        "." + String.valueOf(System.currentTimeMillis()));
    LOG.info("Creating temp file: {}", tempFile);
    return tempFile;
  }

  @VisibleForTesting

View on GitHub (pinned to 2add963021)

Solutions

  1. Remove or stop whatever conflicts on the target file, delete the stale target file, and re-run with -update
  2. Ensure the target's parent directory exists and is writable by the job user
  3. Whitelist .distcp.tmp.* files from cleanup processes while distcp runs
  4. If repeating the copy is expensive, recover the bytes from the named tmp file
Defensive patterns

Strategy: validation

Validate before calling

// ensure exclusive ownership of the destination before the run
if (targetFS.exists(targetFile)) {
  if (!targetFS.delete(targetFile, false)) {
    throw new IOException("cannot clear target for exclusive write: " + targetFile);
  }
}

Try / catch

catch (IOException e) {  // 'Failed to promote tmp-file:... to:...'
  // tmp file named in the message holds the copied bytes; clear the conflict and re-run -update
}

Prevention

When it happens

Trigger: An existing target file cannot be deleted (held open by another writer, permission denied); the target's parent directory was removed while the copy ran; permission loss on the target dir; the tmp file cleaned up before promotion; -append pointing at a file being appended elsewhere.

Common situations: Concurrent distcp jobs or other writers targeting the same file; aggressive tmp-file cleanup jobs; target ACLs changed mid-job; multiple jobs sharing one destination directory.

Related errors


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