apache/hadoop · error · IOException
Could not delete {}
Error message
Could not delete {} What it means
Thrown from FileOutputCommitter.commitTask (FileOutputCommitter.java:602) under commit algorithm v1. Before renaming the task-attempt directory into its committed-task path, v1 first deletes any committed-task directory left by a previous attempt of the same task. If fs.delete(committedTaskPath, true) returns false while the path is known to exist (fs.exists() was just checked), this IOException fails the task commit.
Source
Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/output/FileOutputCommitter.java:602
if (hasOutputPath()) {
context.progress();
if(taskAttemptPath == null) {
taskAttemptPath = getTaskAttemptPath(context);
}
FileSystem fs = taskAttemptPath.getFileSystem(context.getConfiguration());
FileStatus taskAttemptDirStatus;
try {
taskAttemptDirStatus = fs.getFileStatus(taskAttemptPath);
} catch (FileNotFoundException e) {
taskAttemptDirStatus = null;
}
if (taskAttemptDirStatus != null) {
if (algorithmVersion == 1) {
Path committedTaskPath = getCommittedTaskPath(context);
if (fs.exists(committedTaskPath)) {
if (!fs.delete(committedTaskPath, true)) {
throw new IOException("Could not delete " + committedTaskPath);
}
}
if (!fs.rename(taskAttemptPath, committedTaskPath)) {
throw new IOException("Could not rename " + taskAttemptPath + " to "
+ committedTaskPath);
}
LOG.info("Saved output of task '" + attemptId + "' to " +
committedTaskPath);
} else {
// directly merge everything from taskAttemptPath to output directory
mergePaths(fs, taskAttemptDirStatus, outputPath, context);
LOG.info("Saved output of task '" + attemptId + "' to " +
outputPath);
if (context.getConfiguration().getBoolean(
FILEOUTPUTCOMMITTER_TASK_CLEANUP_ENABLED,
FILEOUTPUTCOMMITTER_TASK_CLEANUP_ENABLED_DEFAULT)) {
LOG.debug(String.format(View on GitHub (pinned to 2add963021)
Solutions
- Check ownership/permissions of the committed-task path printed in the message (hadoop fs -ls <outdir>/_temporary) and hadoop fs -rm -r it as an admin or the owning user, then let the task retry
- Run each job into a fresh output directory so no committed-task dirs from previous runs exist
- Ensure the same user (and only that user) runs all attempts of the job
- Switch to mapreduce.fileoutputcommitter.algorithm.version=2 (default in modern Hadoop), which merges directly into the output dir and does not need this delete
Example fix
// job setup: stop reusing the v1 commit path layout across runs
// before
conf.setInt("mapreduce.fileoutputcommitter.algorithm.version", 1);
FileOutputFormat.setOutputPath(job, new Path("/data/shared-out"));
// after
conf.setInt("mapreduce.fileoutputcommitter.algorithm.version", 2);
FileOutputFormat.setOutputPath(job, new Path("/data/out-" + job.getJobName())); Defensive patterns
Strategy: validation
Validate before calling
// pre-submit sanity: the output tree must be owned by / deletable by the job user
FileSystem fs = outDir.getFileSystem(conf);
if (fs.exists(outDir)) {
FileStatus st = fs.getFileStatus(outDir);
FsShellPermissionCheck: verify st.getOwner().equals(currentUser) or writable bits;
} Try / catch
try { committer.commitTask(context); } catch (IOException io) { if (io.getMessage().contains("Could not delete")) { /* inspect committed-task dir ownership; admin delete + allow task retry */ } throw io; } Prevention
- Fresh output dir per run
- Single owning user for the whole job lifecycle
- Avoid mixing v1 committer with reused output directories
When it happens
Trigger: mapreduce.fileoutputcommitter.algorithm.version=1, commitTask() called for a retried task attempt whose committed-task path already exists under <outdir>/_temporary/<appAttemptId>/task_*/, and fs.delete returns false. Concrete causes: no delete permission on that committed directory (often created by a different user in a prior run), a concurrent commit of another attempt of the same task, or FS-level inconsistency.
Common situations: Task retries after a failed attempt under v1; output directory reused across runs by different users so committed-task dirs are owned by someone else; security-hardened clusters where the job user can create but not delete sibling files.
Related errors
- Could not rename {} to {}
- Cannot recover task output for first attempt...
- Unable to recover task %s, output: %s
- Changing job priority in LocalJobRunner is not supported.
- Killing tasks in LocalJobRunner is not supported
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/7476b86703506a33.
Report an issue: GitHub.