{"record":{"id":"b0600b2fda706e4f","repo":"apache/hadoop","slug":"no-committer-defined-in-mapreduce-outputcommitter","errorCode":null,"errorMessage":"No committer defined in mapreduce.outputcommitter.named.classname","messagePattern":"No committer defined in mapreduce\\.outputcommitter\\.named\\.classname","errorType":"validation","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/output/NamedCommitterFactory.java","lineNumber":74,"sourceCode":"        | InvocationTargetException e) {\n      throw new IOException(\"Failed to create \" + clazz\n          + \":\" + e, e);\n    }\n  }\n\n  /**\n   * Load the class named in {@link #NAMED_COMMITTER_CLASS}.\n   * @param context job or task context\n   * @return the committer class\n   * @throws IOException if no committer was defined.\n   */\n  private Class<? extends PathOutputCommitter> loadCommitterClass(\n      JobContext context) throws IOException {\n    Preconditions.checkNotNull(context, \"null context\");\n    Configuration conf = context.getConfiguration();\n    String value = conf.get(NAMED_COMMITTER_CLASS, \"\");\n    if (value.isEmpty()) {\n      throw new IOException(\"No committer defined in \" + NAMED_COMMITTER_CLASS);\n    }\n    return conf.getClass(NAMED_COMMITTER_CLASS,\n        FileOutputCommitter.class, PathOutputCommitter.class);\n  }\n}\n","sourceCodeStart":56,"sourceCodeEnd":80,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/output/NamedCommitterFactory.java#L56-L80","documentation":"NamedCommitterFactory.loadCommitterClass reads mapreduce.outputcommitter.named.classname and treats an empty value as fatal: it throws IOException('No committer defined in mapreduce.outputcommitter.named.classname') before the class is ever loaded. It means the named factory was selected for the output filesystem scheme but no committer implementation was named for it to create.","triggerScenarios":"Setting mapreduce.outputcommitter.factory.scheme.<scheme> (or the default factory key) to NamedCommitterFactory while mapreduce.outputcommitter.named.classname is unset or blank in the effective (final, after job.xml merge) configuration.","commonSituations":"Copy-pasting the factory binding from docs or another cluster without also setting the classname key; a job template that sets the factory per scheme (hdfs, abfs, gcs) but only defines the classname for some jobs; Hive/Spark/Impala overlaying conf that clears the property; typos in the property name so the real value never lands.","solutions":["Set the property: conf.set(\"mapreduce.outputcommitter.named.classname\", FileOutputCommitter.class.getName()) or your PathOutputCommitter implementation.","If you did not intend the named factory, remove the mapreduce.outputcommitter.factory.scheme.* binding so PathOutputCommitterFactory falls back to FileOutputCommitter.","Dump the final configuration on the failing node (conf.get on the task, or -D dump of job.xml) to confirm the property survives job submission.","Check for trailing whitespace/empty string values which the isEmpty() check also rejects."],"exampleFix":"// before: factory selected, committer never named\nconf.set(\"mapreduce.outputcommitter.factory.scheme.hdfs\",\n    \"org.apache.hadoop.mapreduce.lib.output.NamedCommitterFactory\");\n\n// after: name the implementation the factory must create\nconf.set(\"mapreduce.outputcommitter.factory.scheme.hdfs\",\n    \"org.apache.hadoop.mapreduce.lib.output.NamedCommitterFactory\");\nconf.set(\"mapreduce.outputcommitter.named.classname\",\n    \"org.apache.hadoop.mapreduce.lib.output.FileOutputCommitter\");","handlingStrategy":"validation","validationCode":"// fail fast on the client before submission\nString factory = conf.get(\"mapreduce.outputcommitter.factory.scheme.\" + scheme);\nif (factory != null && factory.contains(\"NamedCommitterFactory\")) {\n  String impl = conf.get(\"mapreduce.outputcommitter.named.classname\", \"\");\n  Preconditions.checkArgument(!impl.trim().isEmpty(),\n      \"named factory selected but mapreduce.outputcommitter.named.classname is empty\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  job.waitForCompletion(true);\n} catch (IOException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"No committer defined\")) {\n    // config error: set the classname property and resubmit, do not retry as-is\n  }\n}","preventionTips":["Always set the named classname key and the factory binding together in one conf template.","Assert required committer keys in a job-validation step before submit.","Beware overlays (Hive/Spark setProperty) that can blank keys after your job config."],"tags":["hadoop","mapreduce","output-committer","missing-configuration"],"backgroundTag":"missing-config-value","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}