apache/hadoop · error · IllegalArgumentException
Undefined named output '{}'
Error message
Undefined named output '{}' What it means
The runtime (instance) MultipleOutputs object builds a set of registered channel names from 'mo.namedOutputs' in its constructor. getCollector() validates the requested name against that set and throws this IllegalArgumentException — 'Undefined named output' — when the name is a syntactically valid token (checkNamedOutputName passed) but was never registered with addNamedOutput/addMultiNamedOutput. It fires inside map/reduce code, at the moment the collector is requested.
Source
Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/lib/MultipleOutputs.java:523
}
/**
* Gets the output collector for a multi named output.
*
* @param namedOutput the named output name
* @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() {View on GitHub (pinned to 2add963021)
Solutions
- Register the name in the job driver: MultipleOutputs.addNamedOutput(conf, "channelX", formatClass, keyClass, valueClass)
- Use one shared constant for each channel name across driver and task code
- In tests, seed the JobConf with the same addNamedOutput calls the driver would make
- Debug by printing MultipleOutputs.getNamedOutputsList(conf) (or iterating mos.getNamedOutputs()) to see what the task actually knows
Example fix
// before: driver forgot the registration; reduce() throws
mos.getCollector("alerts", reporter).collect(key, value);
// after: driver registers the channel once
MultipleOutputs.addNamedOutput(conf, "alerts", TextOutputFormat.class, Text.class, Text.class);
// ...and task code uses the same constant
mos.getCollector(ALERTS_OUTPUT, reporter).collect(key, value); Defensive patterns
Strategy: validation
Validate before calling
// verify against the exact conf the task will see
if (!MultipleOutputs.getNamedOutputsList(jobConf).contains(CHANNEL)) {
throw new IllegalStateException(CHANNEL + " not registered; call MultipleOutputs.addNamedOutput first");
}
OutputCollector c = mos.getCollector(CHANNEL, reporter); Type guard
static boolean isRegisteredChannel(JobConf conf, String name) {
return MultipleOutputs.getNamedOutputsList(conf).contains(name);
} Try / catch
try {
mos.getCollector(CHANNEL, reporter).collect(key, value);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Undefined named output")) {
throw new IllegalStateException("channel wiring bug: " + CHANNEL + " missing from mo.namedOutputs", e);
}
throw e;
} Prevention
- Declare channel names as compile-time constants used by both driver and task code
- In tests, build the JobConf with the same addNamedOutput calls as production
- Fail fast: an undefined channel is a wiring bug, never something to catch-and-continue
When it happens
Trigger: mos.getCollector("channelX", reporter) in a Mapper/Reducer where the driver never called MultipleOutputs.addNamedOutput(conf, "channelX", ...). Common trigger is name drift: driver registers 'clicks' while task code asks for 'click', or the named output was registered on a different JobConf than the one the task actually received.
Common situations: Renaming a channel in the driver but not in the mapper/reducer (or vice versa); copy-pasting task code between jobs whose drivers register different channels; unit tests that construct MultipleOutputs with a bare JobConf lacking the mo.namedOutputs entries.
Related errors
- Named output '{}' not defined
- Named output '{}' already alreadyDefined
- Name cannot be NULL or emtpy
- Name cannot be have a '{}' char
- Named output name cannot be 'part'
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/08af713843b718c4.
Report an issue: GitHub.