apache/hadoop · error · IllegalArgumentException

File name can't be empty string

Error message

File name can't be empty string

What it means

GenericOptionsParser.validateFiles backs the -files/-libjars/-archives options: it splits the comma-separated argument and refuses empty names with IllegalArgumentException("File name can't be empty string"). This first branch fires only when the split yields a zero-length array — effectively defensive dead code, because String.split never returns an empty array for a non-null string; the per-element check is the one normally hit. When launched via ServiceLauncher the IAE converts to exit code 40.

Source

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

   * So an input of  /home/user/file1,/home/user/file2 would return
   * file:///home/user/file1,file:///home/user/file2.
   *
   * @param files the input files argument
   * @param expandWildcard whether a wildcard entry is allowed and expanded. If
   * true, any directory followed by a wildcard is a valid entry and is replaced
   * with the list of jars in that directory. It is used to support the wildcard
   * notation in a classpath.
   * @return a comma-separated list of validated and qualified paths, or null
   * if the input files argument is null
   */
  private String validateFiles(String files, boolean expandWildcard)
      throws IOException {
    if (files == null) {
      return null;
    }
    String[] fileArr = files.split(",");
    if (fileArr.length == 0) {
      throw new IllegalArgumentException("File name can't be empty string");
    }
    List<String> finalPaths = new ArrayList<>(fileArr.length);
    for (int i =0; i < fileArr.length; i++) {
      String tmp = fileArr[i];
      if (tmp.isEmpty()) {
        throw new IllegalArgumentException("File name can't be empty string");
      }
      URI pathURI;
      final String wildcard = "*";
      boolean isWildcard = tmp.endsWith(wildcard) && expandWildcard;
      try {
        if (isWildcard) {
          // strip the wildcard
          tmp = tmp.substring(0, tmp.length() - 1);
        }
        // handle the case where a wildcard alone ("*") or the wildcard on the
        // current directory ("./*") is specified
        pathURI = matchesCurrentDirectory(tmp) ?

View on GitHub (pinned to 2add963021)

Solutions

  1. Don't pass the option at all when the list is empty — guard the variable
  2. Strip empty entries and trailing commas from the value before passing it
  3. Log the fully assembled command line before executing to catch empty expansions

Example fix

# before
hadoop jar job.jar -libjars "$EXTRA_JARS" Driver
# after: omit the flag when the variable is empty
EXTRA=()
[ -n "$EXTRA_JARS" ] && EXTRA+=(-libjars "$EXTRA_JARS")
hadoop jar job.jar "${EXTRA[@]}" Driver
Defensive patterns

Strategy: validation

Validate before calling

String sanitize(String commaList) {
  String joined = Arrays.stream(commaList.split(","))
      .map(String::trim).filter(s -> !s.isEmpty())
      .collect(Collectors.joining(","));
  if (joined.isEmpty()) return null; // omit -libjars/-files entirely
  return joined;
}

Prevention

When it happens

Trigger: Passing a degenerate empty value to -files/-libjars/-archives (e.g. an unset shell variable expanding to an empty string) — in practice caught by the sibling per-element check; this length==0 branch itself requires a split result of zero entries, which plain strings cannot produce.

Common situations: Oozie/shell workflows interpolating empty variables into -libjars; pipeline stages that conditionally build jar lists and pass the empty result anyway.

Related errors


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