apache/hadoop · error · IOException

Mkdirs failed to create tar internal dir " + outputDir

Error message

Mkdirs failed to create tar internal dir " + outputDir

What it means

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.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java:1150

    String targetDirPath = outputDir.getCanonicalPath() + File.separator;
    File outputFile = new File(outputDir, entry.getName());
    if (!outputFile.getCanonicalPath().startsWith(targetDirPath)) {
      throw new IOException("expanding " + entry.getName()
          + " would create entry outside of " + outputDir);
    }

    if (entry.isSymbolicLink() || entry.isLink()) {
      String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
      if (!canonicalTargetPath.startsWith(targetDirPath)) {
        throw new IOException(
            "expanding " + entry.getName() + " would create entry outside of " + outputDir);
      }
    }

    if (entry.isDirectory()) {
      File subDir = new File(outputDir, entry.getName());
      if (!subDir.mkdirs() && !subDir.isDirectory()) {
        throw new IOException("Mkdirs failed to create tar internal dir "
            + outputDir);
      }

      for (TarArchiveEntry e : entry.getDirectoryEntries()) {
        unpackEntries(tis, e, subDir);
      }

      return;
    }

    if (entry.isSymbolicLink()) {
      // Create symlink with canonical target path to ensure that we don't extract
      // outside targetDirPath
      String canonicalTargetPath = getCanonicalPath(entry.getLinkName(), outputDir);
      Files.createSymbolicLink(
          FileSystems.getDefault().getPath(outputDir.getPath(), entry.getName()),
          FileSystems.getDefault().getPath(canonicalTargetPath));
      return;

View on GitHub (pinned to 2add963021)

Solutions

  1. Clear the previous partial extraction and re-extract into a clean directory
  2. Verify outputDir is writable and has free space/inodes before starting
  3. Fix policy/mount denials (SELinux context, rw mount) for the extraction root
  4. If a specific FILE blocks an inner directory path, remove it explicitly after confirming it is stale

Example fix

// before
FileUtil.unTar(in, new File("/tmp/x"), false);
// Mkdirs failed to create tar internal dir /tmp/x

// after: extract into a guaranteed-clean directory
Path clean = Files.createTempDirectory("untar-");
FileUtil.unTar(in, clean.toFile(), false);
Defensive patterns

Strategy: validation

Validate before calling

Path clean = Files.createTempDirectory("untar-"); // guaranteed fresh + writable
FileUtil.unTar(in, clean.toFile(), gzipped);

Try / catch

try {
  FileUtil.unTar(in, dir, gzipped);
} catch (IOException e) {
  if (e.getMessage() != null && e.getMessage().contains("tar internal dir")) {
    // message names outputDir, but the failing path is an inner dir: inspect the tree
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: Leftover partial extractions blocking inner dirs; extraction into locked-down /tmp; containers with read-only layers; disk full during CI artifact expansion.

Related errors


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