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
- 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.
- For the LevelDB store also set mapreduce.jobhistory.recovery.store.leveldb.path; for the filesystem store set mapreduce.jobhistory.recovery.store.fs.uri.
- If recovery is not intended, set mapreduce.jobhistory.recovery.enable=false.
- 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
- Set store class and its companion path/URI properties together.
- Use fully qualified class names from the target Hadoop version.
- Smoke-test JHS startup in staging after enabling recovery.
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
- No store location directory configured in mapreduce.jobhisto
- Configuration file not found at {confFile}
- Couldn't open queue configuration at " + xmlInUrl
- ${tokenPath} already exists
- ${keyPath} already exists
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/adc2227a09fa5755.
Report an issue: GitHub.