apache/hadoop · error · IllegalArgumentException

Name output '{}' has not been defined as multi

Error message

Name output '{}' has not been defined as multi

What it means

A named output in MultipleOutputs is either single (one file per task, registered with addNamedOutput) or multi (an unbounded set of files named name_multiName, registered with addMultiNamedOutput, which sets mo.namedOutput.<name>.multi=true). getCollector(name, multiName, reporter) throws this IllegalArgumentException when multiName is not null but the channel was registered as single. The framework refuses to guess which file family you meant.

Source

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

   * @param multiName   the multi name part
   * @param reporter    the reporter
   * @return the output collector for the given named output
   * @throws IOException thrown if output collector could not be created
   */
  @SuppressWarnings({"unchecked"})
  public OutputCollector getCollector(String namedOutput, String multiName,
                                      Reporter reporter)
    throws IOException {

    checkNamedOutputName(namedOutput);
    if (!namedOutputs.contains(namedOutput)) {
      throw new IllegalArgumentException("Undefined named output '" +
        namedOutput + "'");
    }
    boolean multi = isMultiNamedOutput(conf, namedOutput);

    if (!multi && multiName != null) {
      throw new IllegalArgumentException("Name output '" + namedOutput +
        "' has not been defined as multi");
    }
    if (multi) {
      checkTokenName(multiName);
    }

    String baseFileName = (multi) ? namedOutput + "_" + multiName : namedOutput;

    final RecordWriter writer =
      getRecordWriter(namedOutput, baseFileName, reporter);

    return new OutputCollector() {

      @SuppressWarnings({"unchecked"})
      public void collect(Object key, Object value) throws IOException {
        writer.write(key, value);
      }

View on GitHub (pinned to 2add963021)

Solutions

  1. Register the channel as multi: MultipleOutputs.addMultiNamedOutput(conf, "seq", SequenceFileOutputFormat.class, keyClass, valueClass)
  2. If you really want a single file, call getCollector("seq", reporter) without the multiName argument
  3. Keep the single/multi decision in the same place as the registration so driver and task code cannot disagree

Example fix

// before: single registration + multi call -> IllegalArgumentException
MultipleOutputs.addNamedOutput(conf, "seq", SequenceFileOutputFormat.class, LongWritable.class, Text.class);
mos.getCollector("seq", "A", reporter);

// after: multi registration matches the multi call
MultipleOutputs.addMultiNamedOutput(conf, "seq", SequenceFileOutputFormat.class, LongWritable.class, Text.class);
mos.getCollector("seq", "A", reporter);
Defensive patterns

Strategy: validation

Validate before calling

// check the mode before deciding the call shape
if (MultipleOutputs.isMultiNamedOutput(conf, "seq")) {
  collector = mos.getCollector("seq", multiName, reporter);
} else {
  collector = mos.getCollector("seq", reporter);
}

Type guard

static boolean isMulti(JobConf conf, String name) {
  return MultipleOutputs.isMultiNamedOutput(conf, name);
}

Prevention

When it happens

Trigger: Driver registers MultipleOutputs.addNamedOutput(conf, "seq", ...) (single), then task code calls mos.getCollector("seq", "A", reporter) with a second-level name. Typical when the channel was originally multi and someone 'simplified' the driver call to addNamedOutput, or when example code for multi outputs was mixed with a single-output driver.

Common situations: Sharding output by key/category (getCollector("seq", keyCategory, reporter)) where the driver author didn't realize the multi variant needs addMultiNamedOutput; upgrading old job templates that only registered single outputs.

Related errors


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