{"record":{"id":"0997cab52d619435","repo":"apache/hadoop","slug":"mkdirs-failed-to-create-tar-internal-dir-outpu","errorCode":null,"errorMessage":"Mkdirs failed to create tar internal dir \" + outputDir","messagePattern":"Mkdirs failed to create tar internal dir \" \\+ outputDir","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java","lineNumber":1150,"sourceCode":"    String targetDirPath = outputDir.getCanonicalPath() + File.separator;\n    File outputFile = new File(outputDir, entry.getName());\n    if (!outputFile.getCanonicalPath().startsWith(targetDirPath)) {\n      throw new IOException(\"expanding \" + entry.getName()\n          + \" would create entry outside of \" + outputDir);\n    }\n\n    if (entry.isSymbolicLink() || entry.isLink()) {\n      String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);\n      if (!canonicalTargetPath.startsWith(targetDirPath)) {\n        throw new IOException(\n            \"expanding \" + entry.getName() + \" would create entry outside of \" + outputDir);\n      }\n    }\n\n    if (entry.isDirectory()) {\n      File subDir = new File(outputDir, entry.getName());\n      if (!subDir.mkdirs() && !subDir.isDirectory()) {\n        throw new IOException(\"Mkdirs failed to create tar internal dir \"\n            + outputDir);\n      }\n\n      for (TarArchiveEntry e : entry.getDirectoryEntries()) {\n        unpackEntries(tis, e, subDir);\n      }\n\n      return;\n    }\n\n    if (entry.isSymbolicLink()) {\n      // Create symlink with canonical target path to ensure that we don't extract\n      // outside targetDirPath\n      String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);\n      Files.createSymbolicLink(\n          FileSystems.getDefault().getPath(outputDir.getPath(), entry.getName()),\n          FileSystems.getDefault().getPath(canonicalTargetPath));\n      return;","sourceCodeStart":1132,"sourceCodeEnd":1168,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java#L1132-L1168","documentation":"In unpackEntries, when a tar entry is a directory, File subDir = new File(outputDir, entry.getName()) is created via mkdirs(); if mkdirs() fails and subDir.isDirectory() is false it throws IOException(\"Mkdirs failed to create tar internal dir <outputDir>\"). Note the message names outputDir (the parent root), not subDir itself, which is mildly misleading. It means the OS refused to create a directory the archive requires.","triggerScenarios":"unTarUsingJava extracting a tar whose internal directory path cannot be created: read-only outputDir, an existing FILE where an inner directory belongs, SELinux denial, or inode exhaustion.","commonSituations":"Leftover partial extractions blocking inner dirs; extraction into locked-down /tmp; containers with read-only layers; disk full during CI artifact expansion.","solutions":["Clear the previous partial extraction and re-extract into a clean directory","Verify outputDir is writable and has free space/inodes before starting","Fix policy/mount denials (SELinux context, rw mount) for the extraction root","If a specific FILE blocks an inner directory path, remove it explicitly after confirming it is stale"],"exampleFix":"// before\nFileUtil.unTar(in, new File(\"/tmp/x\"), false);\n// Mkdirs failed to create tar internal dir /tmp/x\n\n// after: extract into a guaranteed-clean directory\nPath clean = Files.createTempDirectory(\"untar-\");\nFileUtil.unTar(in, clean.toFile(), false);","handlingStrategy":"validation","validationCode":"Path clean = Files.createTempDirectory(\"untar-\"); // guaranteed fresh + writable\nFileUtil.unTar(in, clean.toFile(), gzipped);","typeGuard":null,"tryCatchPattern":"try {\n  FileUtil.unTar(in, dir, gzipped);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"tar internal dir\")) {\n    // message names outputDir, but the failing path is an inner dir: inspect the tree\n  } else throw e;\n}","preventionTips":["Always extract into a fresh directory; never over a partial previous extraction","Check outputDir.canWrite() and free space first","Resolve SELinux/mount denials on the extraction root"],"tags":["mkdir-failed","untar","permissions","archive-extraction"],"backgroundTag":"mkdir-failed","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}