apache/druid · critical · ServletException
Principals do not exist in the keytab
Error message
Principals do not exist in the keytab
What it means
When the configured principal is '*', the handler derives SPNEGO principals by scanning the keytab for names matching HTTP/.*. If no such HTTP service principals exist in the keytab, there is nothing to authenticate with, and init() throws a ServletException.
Source
Thrown at extensions-core/druid-kerberos/src/main/java/org/apache/druid/security/kerberos/DruidKerberosAuthenticationHandler.java:96
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);
}
for (String spnegoPrincipal : spnegoPrincipals) {
log.info("Login using keytab %s, for principal %s", keytab, spnegoPrincipal);
final KerberosAuthenticator.DruidKerberosConfiguration kerberosConfiguration =
new KerberosAuthenticator.DruidKerberosConfiguration(keytab, spnegoPrincipal);
final LoginContext loginContext =
new LoginContext("", serverSubject, null, kerberosConfiguration);
try {
loginContext.login();View on GitHub (pinned to 9b90983fd2)
Solutions
- Add an HTTP/<host>@<REALM> principal to the keytab via kadmin ktadd
- Or set an explicit principal (instead of '*') matching one present in the keytab
- Verify keytab contents with 'klist -kt /path/to/keytab' and confirm an HTTP/ entry exists
Example fix
// before
props.setProperty("druid.auth.kerberos.serverPrincipal", "*"); // keytab lacks HTTP/ principals
// after
props.setProperty("druid.auth.kerberos.serverPrincipal", "HTTP/broker1.example.com@EXAMPLE.COM"); Defensive patterns
Strategy: validation
Validate before calling
String principalNames = new String(
java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(keytab)),
java.nio.charset.StandardCharsets.ISO_8859_1);
// verify with klist externally:
// klist -kt /path/to/keytab | grep HTTP/ Try / catch
try { handler.init(config); } catch (ServletException e) { if ("Principals do not exist in the keytab".equals(e.getMessage())) { log.error("Keytab lacks HTTP/ principals; run klist -kt"); } throw e; } Prevention
- Run 'klist -kt' on the keytab before enabling wildcard ('*') principal mode
- Only use '*' when the keytab is known to contain HTTP/ service principals
- Prefer explicit principal names to avoid keytab-content dependency
When it happens
Trigger: init(Properties) with PRINCIPAL set to '*' and KerberosUtil.getPrincipalNames(keytab, HTTP/*.*) returning an empty array.
Common situations: Wildcard principal configured but keytab contains only non-HTTP principals (e.g. user or other service principals); keytab for the wrong service; kadmin exported principals with a different prefix than HTTP/.
Related errors
- Failed to login as [%s]
- Keytab does not exist: %s
- Principal not defined in configuration
- Keytab not defined in configuration
- Keytab does not exist:
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/0e962c0ea703cf5a.
Report an issue: GitHub.