{"record":{"id":"e5b2b5929f59b940","repo":"apache/hadoop","slug":"failed-to-rename-to-e5b2b5","errorCode":null,"errorMessage":"Failed to rename {} to {}","messagePattern":"Failed to rename (.+?) to (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/output/FileOutputCommitter.java","lineNumber":482,"sourceCode":"        false,\n        \"Merging data from %s to %s\", from, to)) {\n      reportProgress(context);\n      FileStatus toStat;\n      try {\n        toStat = fs.getFileStatus(to);\n      } catch (FileNotFoundException fnfe) {\n        toStat = null;\n      }\n\n      if (from.isFile()) {\n        if (toStat != null) {\n          if (!fs.delete(to, true)) {\n            throw new IOException(\"Failed to delete \" + to);\n          }\n        }\n\n        if (!fs.rename(from.getPath(), to)) {\n          throw new IOException(\"Failed to rename \" + from + \" to \" + to);\n        }\n      } else if (from.isDirectory()) {\n        if (toStat != null) {\n          if (!toStat.isDirectory()) {\n            if (!fs.delete(to, true)) {\n              throw new IOException(\"Failed to delete \" + to);\n            }\n            renameOrMerge(fs, from, to, context);\n          } else {\n            //It is a directory so merge everything in the directories\n            for (FileStatus subFrom : fs.listStatus(from.getPath())) {\n              Path subTo = new Path(to, subFrom.getPath().getName());\n              mergePaths(fs, subFrom, subTo, context);\n            }\n          }\n        } else {\n          renameOrMerge(fs, from, to, context);\n        }","sourceCodeStart":464,"sourceCodeEnd":500,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/output/FileOutputCommitter.java#L464-L500","documentation":"In the commit phase, FileOutputCommitter.mergePaths moves committed task output from the _temporary area to the final destination with fs.rename(from, to); a false return (failure without exception) becomes IOException('Failed to rename <from> to <to>') at FileOutputCommitter.java:483. Rename success is filesystem-dependent — it fails on permission errors, missing parents, destination-exists semantics, or object stores with non-atomic rename.","triggerScenarios":"Committing a job whose output parent dir lacks write permission; the destination already exists as a file where a directory is needed (or vice versa, in the not-file branches of mergePaths); concurrent committers (AM + task, two jobs, speculative attempts) racing on the same target names; HDFS in safe mode or during NN failover; S3A/ABFS paths without proper committer configuration emulating rename via copy+delete.","commonSituations":"Output directory owned by another user or read-only (chmod 555); reruns into existing output with different file layout; classic MapReduce on object stores (S3) using the default committer; slow metadata operations timing out; algorithm.version=1 tasks committing while another attempt commits the same files.","solutions":["Verify and fix permissions/ownership on the output directory (hadoop fs -chown/-chmod) for the submitting user, including the _temporary subtree","Clear or version the output path per run (hadoop fs -rm -r /out, or /out-$RUNID) to avoid exists-collisions during rename","Eliminate concurrent writers: unique output dirs per job/attempt, disable duplicate submissions, and let only one committer own a path","For object stores, switch to the store-native committer (fs.s3a.committer.name=magic|directory) or a zero-rename committer rather than FileOutputCommitter renames","Check cluster health at the commit timestamp in logs (safe mode, NN failover) and simply retry the job once healthy — commit is idempotent per attempt after cleanup"],"exampleFix":"# before\nhadoop fs -chmod 555 /out            # read-only output dir\nhadoop jar app.jar Driver /in /out   # task commit rename -> 'Failed to rename ... to ...'\n\n# after\nhadoop fs -chmod -R 755 /out\nhadoop fs -rm -r /out/_temporary\nhadoop jar app.jar Driver /in /out\n\n# for S3, prefer a real committer:\n# -Dfs.s3a.committer.name=magic -Dmapreduce.outputcommitter.factory.scheme.s3a=org.apache.hadoop.fs.s3a.commit.S3ACommitterFactory","handlingStrategy":"retry","validationCode":"static void requireCommittableOutput(Path out, Configuration conf) throws IOException {\n  FileSystem fs = out.getFileSystem(conf);\n  Path p = out.getParent() != null ? out.getParent() : out;\n  if (fs.exists(p) && !fs.getFileStatus(p).getPermission().getUserAction().implies(FsAction.WRITE))\n    throw new IllegalStateException(\"No write permission for output parent: \" + p);\n  if (fs.exists(new Path(out, \"_temporary\")))\n    throw new IllegalStateException(\"Stale _temporary dir from a previous attempt; remove it before rerun\");\n}","typeGuard":null,"tryCatchPattern":"catch (IOException e) { if (String.valueOf(e.getMessage()).startsWith(\"Failed to rename\")) { // commit-phase rename failed: verify perms/safe-mode, remove stale _temporary, resubmit once\n  throw new IOException(\"Commit rename failed (\" + e.getMessage() + \") — check output perms, concurrent writers, FS health; clean and retry\", e); } throw e; }","preventionTips":["Use unique output directories per job/run to avoid rename collisions","Grant write permission on the output parent for the submitting user","Avoid the default FileOutputCommitter on S3/ABFS — configure S3A committers (fs.s3a.committer.name=magic|directory)","Treat a single commit failure during NN failover/safe-mode as transient: clean _temporary and retry once cluster is healthy"],"tags":["hadoop","mapreduce","output-committer","commit-phase","rename"],"backgroundTag":"commit-rename-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}