apache/hadoop · error · IllegalArgumentException

Name cannot be have a '{ch}' char

Error message

Name cannot be have a '{ch}' char

What it means

Thrown as IllegalArgumentException from MultipleOutputs.checkTokenName (MultipleOutputs.java:236). After the null/empty check, each character of a named output must be A-Z, a-z, or 0-9; the first character outside those ranges produces 'Name cannot be have a '<ch>' char'. Named outputs become part of config keys and file names, hence the strict token rule.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/output/MultipleOutputs.java:236

   * @param namedOutput named output Name
   * @throws IllegalArgumentException if the output name is not valid.
   */
  private static void checkTokenName(String namedOutput) {
    if (namedOutput == null || namedOutput.length() == 0) {
      throw new IllegalArgumentException(
        "Name cannot be NULL or emtpy");
    }
    for (char ch : namedOutput.toCharArray()) {
      if ((ch >= 'A') && (ch <= 'Z')) {
        continue;
      }
      if ((ch >= 'a') && (ch <= 'z')) {
        continue;
      }
      if ((ch >= '0') && (ch <= '9')) {
        continue;
      }
      throw new IllegalArgumentException(
        "Name cannot be have a '" + ch + "' char");
    }
  }

  /**
   * Checks if output name is valid.
   *
   * name cannot be the name used for the default output
   * @param outputPath base output Name
   * @throws IllegalArgumentException if the output name is not valid.
   */
  private static void checkBaseOutputPath(String outputPath) {
    if (outputPath.equals(FileOutputFormat.PART)) {
      throw new IllegalArgumentException("output name cannot be 'part'");
    }
  }
  
  /**

View on GitHub (pinned to 2add963021)

Solutions

  1. Use letters and digits only: 'myoutput', 'out1', 'salesEUR'
  2. Sanitize dynamic names: strip or replace disallowed characters before calling addNamedOutput/write
  3. Put the fancy formatting into the baseOutputPath argument of mos.write(name, k, v, baseOutputPath) instead of the channel name — paths there may contain '/'

Example fix

// before
MultipleOutputs.addNamedOutput(job, "user-clicks", TextOutputFormat.class, ...);

// after
MultipleOutputs.addNamedOutput(job, "userclicks", TextOutputFormat.class, ...);
// and keep the pretty name in the file path instead:
mos.write("userclicks", key, value, "user-clicks/r-0001");
Defensive patterns

Strategy: validation

Validate before calling

// sanitize dynamic names to the allowed alphabet
static String sanitizeChannel(String raw) {
  return raw == null ? null : raw.replaceAll("[^A-Za-z0-9]", "");
}

Type guard

static boolean isValidMultipleOutputsToken(String name) {
  if (name == null || name.isEmpty()) return false;
  for (char ch : name.toCharArray()) {
    if (!((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'))) return false;
  }
  return !name.equals("part");
}

Prevention

When it happens

Trigger: addNamedOutput or write with names containing '-', '_', '.', '/', or spaces: 'my-output', 'out_1', 'sales.eur', 'raw data'. All fail because hyphen/underscore/dot/space are not in the allowed ranges.

Common situations: Porting old-API MultipleTextOutputFormat code where arbitrary file-name fragments were allowed; deriving channel names from dates ('2026-08-22') or domain strings ('user-clicks') without sanitizing.

Related errors


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