apache/hadoop · error · IllegalArgumentException
No application program defined.
Error message
No application program defined.
What it means
Thrown by org.apache.hadoop.mapred.pipes.Submitter while assembling a Hadoop Pipes job configuration. setJobConf reads the native C++ binary location via getExecutable(conf), which resolves the config key 'mapreduce.pipes.executable' (Submitter.EXECUTABLE). A Pipes job is only a wrapper around a native binary, so when the lookup returns null, submission aborts with IllegalArgumentException('No application program defined.') before anything is uploaded.
Source
Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapred/pipes/Submitter.java:314
}
}
String textClassname = Text.class.getName();
setIfUnset(conf, MRJobConfig.MAP_OUTPUT_KEY_CLASS, textClassname);
setIfUnset(conf, MRJobConfig.MAP_OUTPUT_VALUE_CLASS, textClassname);
setIfUnset(conf, MRJobConfig.OUTPUT_KEY_CLASS, textClassname);
setIfUnset(conf, MRJobConfig.OUTPUT_VALUE_CLASS, textClassname);
// Use PipesNonJavaInputFormat if necessary to handle progress reporting
// from C++ RecordReaders ...
if (!getIsJavaRecordReader(conf) && !getIsJavaMapper(conf)) {
conf.setClass(Submitter.INPUT_FORMAT,
conf.getInputFormat().getClass(), InputFormat.class);
conf.setInputFormat(PipesNonJavaInputFormat.class);
}
String exec = getExecutable(conf);
if (exec == null) {
throw new IllegalArgumentException("No application program defined.");
}
// add default debug script only when executable is expressed as
// <path>#<executable>
if (exec.contains("#")) {
// set default gdb commands for map and reduce task
String defScript = "$HADOOP_HOME/src/c++/pipes/debug/pipes-default-script";
setIfUnset(conf, MRJobConfig.MAP_DEBUG_SCRIPT,defScript);
setIfUnset(conf, MRJobConfig.REDUCE_DEBUG_SCRIPT,defScript);
}
URI[] fileCache = JobContextImpl.getCacheFiles(conf);
if (fileCache == null) {
fileCache = new URI[1];
} else {
URI[] tmp = new URI[fileCache.length+1];
System.arraycopy(fileCache, 0, tmp, 1, fileCache.length);
fileCache = tmp;
}
try {View on GitHub (pinned to 2add963021)
Solutions
- Pass the binary to the launcher: hadoop pipes -program /path/to/wordcount -input <in> -output <out>
- Or set the property explicitly before running: jobConf.set(Submitter.EXECUTABLE, "/path/to/wordcount")
- If the binary must ship via distributed cache, use a '<path>#<linkname>' value (the code then also installs default debug scripts when it sees '#')
- Guard the call: assert Submitter.getExecutable(conf) != null before runJob to fail with your own clearer message
Example fix
// before
JobConf conf = new JobConf(MyPipe.class);
conf.set("hadoop.pipes.executable", "/tmp/wordcount"); // wrong key, silently ignored
Submitter.runJob(conf); // IllegalArgumentException: No application program defined.
// after
JobConf conf = new JobConf(MyPipe.class);
conf.set(Submitter.EXECUTABLE, "/tmp/wordcount#wordcount"); // mapreduce.pipes.executable
Submitter.runJob(conf); Defensive patterns
Strategy: validation
Validate before calling
// before running a Pipes job
if (Submitter.getExecutable(conf) == null) {
throw new IllegalStateException(
"'mapreduce.pipes.executable' (Submitter.EXECUTABLE) is not set; "
+ "pass -program to the hadoop pipes command or set the property");
}
Submitter.runJob(conf); Try / catch
try {
Submitter.runJob(conf);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("No application program")) {
// report missing -program / mapreduce.pipes.executable distinctly
throw new IllegalStateException("Pipes executable missing", e);
}
throw e;
} Prevention
- Make the build fail if the C++ binary is missing so CI never submits without it
- Centralize Pipes configuration in one place that always sets Submitter.EXECUTABLE
- Prefer the 'path#linkname' form so the binary is also shipped via distributed cache
When it happens
Trigger: Invoking the 'hadoop pipes' launcher without the -program option; calling Submitter.runJob(jobConf)/setJobConf with a JobConf that never set 'mapreduce.pipes.executable'; setting the old Hadoop 1.x key name 'hadoop.pipes.executable' instead of the current one, so getExecutable returns null at Submitter.java:312.
Common situations: Porting Pipes jobs from Hadoop 1.x where the property key differed; CI pipelines that build the C++ binary conditionally and skip setting the property when the build step fails; submitting a Pipes job through Oozie or a workflow engine whose job.xml omits the property.
Related errors
- Invalid specification for distributed-cache artifacts of typ
- SequenceFileAsBinaryOutputFormat doesn't support Record Comp
- Job in state {} instead of {}
- {} is incompatible with {} mode.
- Not submitting job. Job directory {} already exists!! This i
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/ef7ede9c0613115a.
Report an issue: GitHub.