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;
}
@VisibleForTestingView on GitHub (pinned to 2add963021)
Solutions
- Remove or stop whatever conflicts on the target file, delete the stale target file, and re-run with -update
- Ensure the target's parent directory exists and is writable by the job user
- Whitelist .distcp.tmp.* files from cleanup processes while distcp runs
- 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
- One writer per target file; never overlap distcp jobs on one destination
- Protect .distcp.tmp.* files from cleanup processes during jobs
- Avoid -append onto files that other processes append to
- Verify delete permission on pre-existing target files before starting
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
- Interrupted while copying objects (copy)
- Target-path can't be committed to because it exists at {fina
- Atomic commit failed. Temporary data in {workDir}, Unable to
- Fail to rename tmp file (={tmp}) to destination file (={dst}
- key + ": No such file or directory."
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/8fe73eaa0d075ded.
Report an issue: GitHub.