apache/hadoop · error · FileNotFoundException

${path} is not a directory.

Error message

${path} is not a directory.

What it means

expandWildcard resolves the directory part of a wildcard entry such as `-libjars 'dir/*'`; if the FileStatus of that path is not a directory it throws FileNotFoundException('<path> is not a directory.'). The wildcard suffix was applied to something that is a regular file, so there is nothing to enumerate.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/GenericOptionsParser.java:499

        }
      }
    }
    if (finalPaths.isEmpty()) {
      throw new IllegalArgumentException("Path " + files + " cannot be empty.");
    }
    return StringUtils.join(",", finalPaths);
  }

  private boolean matchesCurrentDirectory(String path) {
    return path.isEmpty() || path.equals(Path.CUR_DIR) ||
        path.equals(Path.CUR_DIR + File.separator);
  }

  private void expandWildcard(List<String> finalPaths, Path path, FileSystem fs)
      throws IOException {
    FileStatus status = fs.getFileStatus(path);
    if (!status.isDirectory()) {
      throw new FileNotFoundException(path + " is not a directory.");
    }
    // get all the jars in the directory
    List<Path> jars = FileUtil.getJarsInDirectory(path.toString(),
        fs.equals(FileSystem.getLocal(conf)));
    if (jars.isEmpty()) {
      LOG.warn(path + " does not have jars in it. It will be ignored.");
    } else {
      for (Path jar: jars) {
        finalPaths.add(jar.makeQualified(fs.getUri(),
            fs.getWorkingDirectory()).toString());
      }
    }
  }

  /**
   * Windows powershell and cmd can parse key=value themselves, because
   * /pkey=value is same as /pkey value under windows. However this is not
   * compatible with how we get arbitrary key values in -Dkey=value format.

View on GitHub (pinned to 2add963021)

Solutions

  1. Apply the /* wildcard only to directories
  2. Fix the script to concatenate the directory portion with /*
  3. If the target is supposed to be a directory, replace the file occupying the path

Example fix

# before: BASE already includes the jar filename
hadoop jar job.jar -libjars "${BASE}/*" Driver
# after
hadoop jar job.jar -libjars "$(dirname "$BASE")/*" Driver
Defensive patterns

Strategy: validation

Validate before calling

import java.nio.file.*;
String dir = wildcardPath.substring(0, wildcardPath.length() - 2); // strip '/*'
if (!Files.isDirectory(Paths.get(dir))) {
  throw new IllegalArgumentException("wildcard base is not a directory: " + dir);
}

Try / catch

catch (FileNotFoundException e) {
  // expandWildcard hit a non-directory: the /* was appended to a file path
  log.error("apply /* only to directories: {}", e.getMessage());
}

Prevention

When it happens

Trigger: -libjars '/path/lib/some.jar/*' — appending /* to a file path instead of a directory; a symlink in the wildcard prefix resolving to a file; scripts concatenating ${BASE}/* where BASE already includes a filename.

Common situations: Path variables that may hold either a file or a directory; copy-pasted commands mixing explicit jars and wildcard notation; symlinked lib paths changing target type.

Related errors


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