apache/hadoop · error · IllegalArgumentException

Counters are enabled, Reporter cannot be NULL

Error message

Counters are enabled, Reporter cannot be NULL

What it means

MultipleOutputs can optionally maintain one counter per named output (group = MultipleOutputs class name), enabled with MultipleOutputs.setCountersEnabled(conf, true) — by default counters are disabled. When a writer for a named output must be created and counters are enabled, the Reporter passed to getCollector() is needed to register/increment those counters, so getRecordWriter() throws this IllegalArgumentException if reporter is null. This is the first of two identical checks, performed before the underlying writer is created.

Source

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

   * Returns iterator with the defined name outputs.
   *
   * @return iterator with the defined named outputs
   */
  public Iterator<String> getNamedOutputs() {
    return namedOutputs.iterator();
  }


  // by being synchronized MultipleOutputTask can be use with a
  // MultithreaderMapRunner.
  private synchronized RecordWriter getRecordWriter(String namedOutput,
                                                    String baseFileName,
                                                    final Reporter reporter)
    throws IOException {
    RecordWriter writer = recordWriters.get(baseFileName);
    if (writer == null) {
      if (countersEnabled && reporter == null) {
        throw new IllegalArgumentException(
          "Counters are enabled, Reporter cannot be NULL");
      }
      JobConf jobConf = new JobConf(conf);
      jobConf.set(InternalFileOutputFormat.CONFIG_NAMED_OUTPUT, namedOutput);
      FileSystem fs = FileSystem.get(conf);
      writer =
        outputFormat.getRecordWriter(fs, jobConf, baseFileName, reporter);

      if (countersEnabled) {
        if (reporter == null) {
          throw new IllegalArgumentException(
            "Counters are enabled, Reporter cannot be NULL");
        }
        writer = new RecordWriterWithCounter(writer, baseFileName, reporter);
      }

      recordWriters.put(baseFileName, writer);
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Always pass the Reporter given to map()/reduce(): mos.getCollector("text", reporter)
  2. Thread the Reporter through helper methods that ultimately call getCollector
  3. If no counters are needed, simply do not enable them — setCountersEnabled(conf, false) or omit the call (default is disabled)
  4. In unit tests, pass a dummy Reporter (e.g. Reporter.NULL in the mapred API or a stub) instead of null

Example fix

// before: counters enabled but reporter dropped
MultipleOutputs.setCountersEnabled(conf, true);
mos.getCollector("text", null).collect(key, value);

// after: pass the reporter received by map()/reduce()
public void reduce(K key, Iterator<V> values, OutputCollector out, Reporter reporter) {
  mos.getCollector("text", reporter).collect(key, value);
}
Defensive patterns

Strategy: validation

Validate before calling

// fetch collectors through one helper that owns the reporter contract
private OutputCollector collector(String name, Reporter reporter) throws IOException {
  if (MultipleOutputs.getCountersEnabled(conf) && reporter == null) {
    throw new IllegalStateException("a Reporter is required when mo.counters is enabled");
  }
  return mos.getCollector(name, reporter);
}

Prevention

When it happens

Trigger: MultipleOutputs.setCountersEnabled(conf, true) in the driver, then at task time a call like mos.getCollector("text", null) or mos.getCollector("seq", "A", null). Typical in unit tests or in code paths where the Reporter from map()/reduce() was not threaded through (stored in a wrapper, mocked away, or dropped when getCollector is called from a helper class).

Common situations: Enabling counters for the nice per-channel record counts, then reusing mapper/reducer code in a local test harness that passes null instead of a Reporter; refactoring that moves getCollector calls into helpers which don't receive the reporter parameter.

Related errors


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