apache/hadoop · error · IllegalArgumentException

Configured mapreduce.local.map.tasks.maximum must be >= 1

Error message

Configured mapreduce.local.map.tasks.maximum must be >= 1

What it means

LocalJobRunner.createMapExecutor sizes its map thread pool from mapreduce.local.map.tasks.maximum (LOCAL_MAX_MAPS, default 1). A configured value below 1 - zero or negative - fails fast with IllegalArgumentException before the local job starts.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-common/src/main/java/org/apache/hadoop/mapred/LocalJobRunner.java:417

      for (int i = 0; i < numReduces; i++) {
        this.reduceCounters[i] = new Counters();
      }

      this.numMapTasks = numMaps;
      this.numReduceTasks = numReduces;
    }

    /**
     * Creates the executor service used to run map tasks.
     *
     * @return an ExecutorService instance that handles map tasks
     */
    protected synchronized ExecutorService createMapExecutor() {

      // Determine the size of the thread pool to use
      int maxMapThreads = job.getInt(LOCAL_MAX_MAPS, 1);
      if (maxMapThreads < 1) {
        throw new IllegalArgumentException(
            "Configured " + LOCAL_MAX_MAPS + " must be >= 1");
      }
      maxMapThreads = Math.min(maxMapThreads, this.numMapTasks);
      maxMapThreads = Math.max(maxMapThreads, 1); // In case of no tasks.

      LOG.debug("Starting mapper thread pool executor.");
      LOG.debug("Max local threads: " + maxMapThreads);
      LOG.debug("Map tasks to process: " + this.numMapTasks);

      // Create a new executor service to drain the work queue.
      ThreadFactory tf = new ThreadFactoryBuilder()
        .setNameFormat("LocalJobRunner Map Task Executor #%d")
        .build();
      ExecutorService executor = HadoopExecutors.newFixedThreadPool(
          maxMapThreads, tf);

      return executor;
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Set the property to 1 or higher (for example 4), or remove it to fall back to the default 1
  2. If set programmatically, guard setMaxMapThreads with Math.max(1, n)
  3. Inspect the failing job's job.xml to find which source set the bad value

Example fix

// before
conf.setInt("mapreduce.local.map.tasks.maximum", 0);

// after
conf.setInt("mapreduce.local.map.tasks.maximum", 4);
Defensive patterns

Strategy: validation

Validate before calling

int maxMaps = conf.getInt("mapreduce.local.map.tasks.maximum", 1);
if (maxMaps < 1) {
  throw new IllegalArgumentException(
      "mapreduce.local.map.tasks.maximum must be >= 1, got " + maxMaps);
}
// safe to run the local job

Prevention

When it happens

Trigger: Configuration sets mapreduce.local.map.tasks.maximum to 0 or a negative number - via an XML file, -D on the command line, or LocalJobRunner's setMaxMapThreads API (LocalJobRunner.java:966).

Common situations: Tuning templates copied from mapreduce.job.maps; environment-specific overrides with a placeholder value of 0; an attempt to serialize local maps; property written into the wrong key by mistake.

Related errors


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