apache/hadoop · error · IllegalArgumentException
Configured mapreduce.local.reduce.tasks.maximum must be >= 1
Error message
Configured mapreduce.local.reduce.tasks.maximum must be >= 1
What it means
LocalJobRunner.createReduceExecutor sizes its reduce thread pool from mapreduce.local.reduce.tasks.maximum (LOCAL_MAX_REDUCES, 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:447
.setNameFormat("LocalJobRunner Map Task Executor #%d")
.build();
ExecutorService executor = HadoopExecutors.newFixedThreadPool(
maxMapThreads, tf);
return executor;
}
/**
* Creates the executor service used to run reduce tasks.
*
* @return an ExecutorService instance that handles reduce tasks
*/
protected synchronized ExecutorService createReduceExecutor() {
// Determine the size of the thread pool to use
int maxReduceThreads = job.getInt(LOCAL_MAX_REDUCES, 1);
if (maxReduceThreads < 1) {
throw new IllegalArgumentException(
"Configured " + LOCAL_MAX_REDUCES + " must be >= 1");
}
maxReduceThreads = Math.min(maxReduceThreads, this.numReduceTasks);
maxReduceThreads = Math.max(maxReduceThreads, 1); // In case of no tasks.
LOG.debug("Starting reduce thread pool executor.");
LOG.debug("Max local threads: " + maxReduceThreads);
LOG.debug("Reduce tasks to process: " + this.numReduceTasks);
// Create a new executor service to drain the work queue.
ExecutorService executor = HadoopExecutors.newFixedThreadPool(
maxReduceThreads);
return executor;
}
/** Run a set of tasks and waits for them to complete. */
private void runTasks(List<RunnableWithThrowable> runnables,View on GitHub (pinned to 2add963021)
Solutions
- Set the property to 1 or higher, or remove it to fall back to the default 1
- Guard programmatic setMaxReduceThreads calls with Math.max(1, n)
- Inspect the failing job's job.xml to find which source set the bad value
Example fix
// before
conf.setInt("mapreduce.local.reduce.tasks.maximum", 0);
// after
conf.setInt("mapreduce.local.reduce.tasks.maximum", 2); Defensive patterns
Strategy: validation
Validate before calling
int maxReduces = conf.getInt("mapreduce.local.reduce.tasks.maximum", 1);
if (maxReduces < 1) {
throw new IllegalArgumentException(
"mapreduce.local.reduce.tasks.maximum must be >= 1, got " + maxReduces);
}
// safe to run the local job Prevention
- Validate both mapreduce.local.*.tasks.maximum values in a shared config-check before any local run
- Do not copy mapreduce.job.reduces tuning into the local-runner keys
- Clamp programmatic setMaxReduceThreads calls with Math.max(1, n)
When it happens
Trigger: Configuration sets mapreduce.local.reduce.tasks.maximum to 0 or a negative number - via an XML file, -D on the command line, or LocalJobRunner's setMaxReduceThreads API (LocalJobRunner.java:987).
Common situations: Same shape as the map-side error: copied tuning values, placeholder zeros in environment configs, attempts to serialize local reduces, property-name mix-ups with mapreduce.job.reduces.
Related errors
- Configured mapreduce.local.map.tasks.maximum must be >= 1
- "Not creating intermediate history logDir: [" + doneDirPath
- Missing Log Directory for History
- Only one of the following keys can be specified for a single
- ShuffleProvider Service: {} was NOT found in the list of aux
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/ac52ccabcd6739f6.
Report an issue: GitHub.