apache/druid · critical · ServletException
Keytab does not exist: %s
Error message
Keytab does not exist: %s
What it means
init() checks that the configured keytab file exists on local disk after confirming it is non-blank. If new File(keytab).exists() is false, a ServletException is thrown with the path embedded in the message, aborting handler initialization.
Source
Thrown at extensions-core/druid-kerberos/src/main/java/org/apache/druid/security/kerberos/DruidKerberosAuthenticationHandler.java:87
}
}
loginContexts.clear();
}
@Override
public void init(Properties config) throws ServletException
{
try {
String principal = config.getProperty(PRINCIPAL);
if (principal == null || principal.trim().length() == 0) {
throw new ServletException("Principal not defined in configuration");
}
keytab = config.getProperty(KEYTAB, keytab);
if (keytab == null || keytab.trim().length() == 0) {
throw new ServletException("Keytab not defined in configuration");
}
if (!new File(keytab).exists()) {
throw new ServletException("Keytab does not exist: " + keytab);
}
// use all SPNEGO principals in the keytab if a principal isn't
// specifically configured
final String[] spnegoPrincipals;
if ("*".equals(principal)) {
spnegoPrincipals = KerberosUtil.getPrincipalNames(keytab, Pattern.compile("HTTP/.*"));
if (spnegoPrincipals.length == 0) {
throw new ServletException("Principals do not exist in the keytab");
}
} else {
spnegoPrincipals = new String[]{principal};
}
String nameRules = config.getProperty(NAME_RULES, null);
if (nameRules != null) {
KerberosName.setRules(nameRules);
}View on GitHub (pinned to 9b90983fd2)
Solutions
- Create/deploy the keytab at the exact configured path on every host running the service
- Correct the druid.auth.kerberos.serverKeytab value to the actual keytab path
- Check filesystem permissions/SELinux so the druid process can stat the file
- Regenerate the keytab with kadmin: ktadd -k /path/http.keytab HTTP/host@REALM if it was deleted
Example fix
// before
props.setProperty("druid.auth.kerberos.serverKeytab", "/etc/security/keytabs/http_old.keytab");
// after
props.setProperty("druid.auth.kerberos.serverKeytab", "/etc/security/keytabs/http_broker1.keytab"); Defensive patterns
Strategy: validation
Validate before calling
String keytab = props.getProperty("druid.auth.kerberos.serverKeytab");
if (keytab == null || !new java.io.File(keytab.trim()).exists()) {
throw new IllegalStateException("Keytab file not found on this host: " + keytab);
} Try / catch
try { handler.init(config); } catch (ServletException e) { if (e.getMessage().startsWith("Keytab does not exist")) { log.error("Deploy keytab at: {}", e.getMessage()); } throw e; } Prevention
- Deploy keytabs to identical absolute paths on all cluster nodes
- Include keytab presence checks in node startup/health scripts
- Bake or mount keytabs in container images before service start
When it happens
Trigger: init(Properties) invoked with a non-empty KEYTAB value that points to a non-existent file path on the broker/router host.
Common situations: Keytab deployed only on some nodes of the cluster; path typo or wrong hostname in keytab file; SELinux/permissions causing the path to be unreadable; keytab regenerated with a different filename after an upgrade.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Keytab does not exist:
- Principals do not exist in the keytab
- Keytab not defined in configuration
- Failed to login as [%s]
- Principal not defined in configuration
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/9f8b15434f38e8d4.
Report an issue: GitHub.