apache/hadoop · critical · RuntimeException

Unable to locate storage class, check mapreduce.jobhistory.r

Error message

Unable to locate storage class, check mapreduce.jobhistory.recovery.store.class

What it means

HistoryServerStateStoreServiceFactory.getStore selects the state store implementation when recovery is enabled. conf.getClass for mapreduce.jobhistory.recovery.store.class returning null (property unset) triggers this RuntimeException and aborts JHS startup. A typo'd class value instead surfaces a ClassNotFoundException from conf.getClass, so this exact message specifically means the property is missing.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/HistoryServerStateStoreServiceFactory.java:42

public class HistoryServerStateStoreServiceFactory {

  /**
   * Constructs an instance of the configured storage class
   * 
   * @param conf the configuration
   * @return the state storage instance
   */
  public static HistoryServerStateStoreService getStore(Configuration conf) {
    Class<? extends HistoryServerStateStoreService> storeClass =
        HistoryServerNullStateStoreService.class;
    boolean recoveryEnabled = conf.getBoolean(
        JHAdminConfig.MR_HS_RECOVERY_ENABLE,
        JHAdminConfig.DEFAULT_MR_HS_RECOVERY_ENABLE);
    if (recoveryEnabled) {
      storeClass = conf.getClass(JHAdminConfig.MR_HS_STATE_STORE, null,
          HistoryServerStateStoreService.class);
      if (storeClass == null) {
        throw new RuntimeException("Unable to locate storage class, check "
            + JHAdminConfig.MR_HS_STATE_STORE);
      }
    }
    return ReflectionUtils.newInstance(storeClass, conf);
  }
}

View on GitHub (pinned to 2add963021)

Solutions

  1. Set mapreduce.jobhistory.recovery.store.class to org.apache.hadoop.mapreduce.v2.hs.HistoryServerLeveldbStateStoreService or org.apache.hadoop.mapreduce.v2.hs.HistoryServerFileSystemStateStoreService in mapred-site.xml.
  2. For the LevelDB store also set mapreduce.jobhistory.recovery.store.leveldb.path; for the filesystem store set mapreduce.jobhistory.recovery.store.fs.uri.
  3. If recovery is not intended, set mapreduce.jobhistory.recovery.enable=false.
  4. Restart the JobHistoryServer.

Example fix

<!-- before -->
<property>
  <name>mapreduce.jobhistory.recovery.enable</name>
  <value>true</value>
</property>

<!-- after -->
<property>
  <name>mapreduce.jobhistory.recovery.enable</name>
  <value>true</value>
</property>
<property>
  <name>mapreduce.jobhistory.recovery.store.class</name>
  <value>org.apache.hadoop.mapreduce.v2.hs.HistoryServerLeveldbStateStoreService</value>
</property>
Defensive patterns

Strategy: validation

Validate before calling

# fail fast before JHS start: recovery enabled requires a store class
if grep -q 'mapreduce.jobhistory.recovery.enable.*true' /etc/hadoop/conf/mapred-site.xml; then
  grep -q 'mapreduce.jobhistory.recovery.store.class' /etc/hadoop/conf/mapred-site.xml \
    || { echo 'mapreduce.jobhistory.recovery.store.class missing'; exit 1; }
fi

Prevention

When it happens

Trigger: mapreduce.jobhistory.recovery.enable=true without mapreduce.jobhistory.recovery.store.class set; configuration enabling recovery in only some config files; recovery turned on by a management tool without the companion store class.

Common situations: Following recovery documentation that omits the store class; partial config rollout; enabling recovery for testing and forgetting the store implementation.

Related errors


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