apache/hadoop · error · IOException
Running in secure mode, but config doesn't have a keytab for
Error message
Running in secure mode, but config doesn't have a keytab for key:
What it means
SecurityUtil.login(conf, keytabFileKey, userNameKey, hostname) performs keytab login for daemons. When Kerberos is enabled (UserGroupInformation.isSecurityEnabled) but conf.get(keytabFileKey) is null or empty, it throws IOException naming the missing config key (e.g. dfs.namenode.keytab.file) so the operator knows exactly which property to set.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/SecurityUtil.java:328
* the key to look for keytab file in conf
* @param userNameKey
* the key to look for user's Kerberos principal name in conf
* @param hostname
* hostname to use for substitution
* @throws IOException if the config doesn't specify a keytab
*/
@InterfaceAudience.Public
@InterfaceStability.Evolving
public static void login(final Configuration conf,
final String keytabFileKey, final String userNameKey, String hostname)
throws IOException {
if(! UserGroupInformation.isSecurityEnabled())
return;
String keytabFilename = conf.get(keytabFileKey);
if (keytabFilename == null || keytabFilename.length() == 0) {
throw new IOException(
"Running in secure mode, but config doesn't have a keytab for key: " + keytabFileKey);
}
String principalConfig = conf.get(userNameKey, System
.getProperty("user.name"));
String principalName = SecurityUtil.getServerPrincipal(principalConfig,
hostname);
UserGroupInformation.loginUserFromKeytab(principalName, keytabFilename);
}
/**
* create the service name for a Delegation token
* @param uri of the service
* @param defPort is used if the uri lacks a port
* @return the token service, or null if no authority
* @see #buildTokenService(InetSocketAddress)
*/
public static String buildDTServiceName(URI uri, int defPort) {View on GitHub (pinned to 2add963021)
Solutions
- Set the keytab property named in the message to the path of the daemon's keytab file
- Set the matching principal property (userNameKey, e.g. dfs.namenode.kerberos.principal) as well
- Confirm the file exists and is readable by the daemon user: klist -kt <path>
- Redeploy identical configs to all nodes and restart the daemon
Example fix
<!-- before --> <property><name>dfs.namenode.keytab.file</name><value></value></property> <!-- after --> <property><name>dfs.namenode.keytab.file</name><value>/etc/security/keytab/nn.service.keytab</value></property>
Defensive patterns
Strategy: validation
Validate before calling
String keytab = conf.get(keytabFileKey);
if (UserGroupInformation.isSecurityEnabled()
&& (keytab == null || keytab.isEmpty())) {
throw new IOException("Missing required keytab config: " + keytabFileKey
+ " while Kerberos is enabled");
}
SecurityUtil.login(conf, keytabFileKey, userNameKey, hostname); Prevention
- Fail fast at startup: check every keytab property when hadoop.security.authentication=kerberos
- Verify keytab files exist and are readable by the daemon user before restart
- Keep principal and keytab properties adjacent in config templates so they are set together
When it happens
Trigger: hadoop.security.authentication=kerberos while the daemon keytab property (dfs.namenode.keytab.file, mapreduce.jobhistory.keytab.file, etc.) is unset, empty, or misspelled, and the daemon calls SecurityUtil.login at startup.
Common situations: Enabling security on an existing cluster but forgetting daemon keytab configs; XML property-name typos; an empty value overriding a valid one later in the config chain.
Related errors
- Invalid rule: ${remaining}
- hadoop.security.dns.nameserver requires hadoop.security.dns.
- Security is enabled but block access tokens (via dfs.block.a
- H01
- No secret in signature secret file: ${signatureSecretFile}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/92350e5de146c135.
Report an issue: GitHub.