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

  1. Pass the binary to the launcher: hadoop pipes -program /path/to/wordcount -input <in> -output <out>
  2. Or set the property explicitly before running: jobConf.set(Submitter.EXECUTABLE, "/path/to/wordcount")
  3. If the binary must ship via distributed cache, use a '<path>#<linkname>' value (the code then also installs default debug scripts when it sees '#')
  4. 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

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


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