apache/hadoop · error · KerberosAuthException
login must be done first
Error message
login must be done first
What it means
reloginFromTicketCache requires a login context on the UGI. If the auth method is ticket-based (isFromTicket() true) but getLogin() returns null, it throws KerberosAuthException(MUST_FIRST_LOGIN) - the mirror of the keytab variant.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java:1328
* The Subject field of this UserGroupInformation object is updated to have
* the new credentials.
* @throws IOException raised on errors performing I/O.
* @throws KerberosAuthException on a failure
*/
@InterfaceAudience.Public
@InterfaceStability.Evolving
public void reloginFromTicketCache() throws IOException {
reloginFromTicketCache(false);
}
private void reloginFromTicketCache(boolean ignoreLastLoginTime)
throws IOException {
if (!shouldRelogin() || !isFromTicket()) {
return;
}
HadoopLoginContext login = getLogin();
if (login == null) {
throw new KerberosAuthException(MUST_FIRST_LOGIN);
}
relogin(login, ignoreLastLoginTime);
}
private void relogin(HadoopLoginContext login, boolean ignoreLastLoginTime)
throws IOException {
// ensure the relogin is atomic to avoid leaving credentials in an
// inconsistent state. prevents other ugi instances, SASL, and SPNEGO
// from accessing or altering credentials during the relogin.
synchronized(login.getSubjectLock()) {
// another racing thread may have beat us to the relogin.
if (login == getLogin()) {
unprotectedRelogin(login, ignoreLastLoginTime);
}
}
}
private void unprotectedRelogin(HadoopLoginContext login,View on GitHub (pinned to 2add963021)
Solutions
- Use UserGroupInformation.loginUserFromTicketCache() (i.e., kinit first, then login) to obtain the UGI
- Check UserGroupInformation.isLoginTicketBased() before calling reloginFromTicketCache
- If the login context is missing, re-login from scratch rather than relogging
Defensive patterns
Strategy: validation
Validate before calling
if (!UserGroupInformation.isLoginTicketBased()) {
return; // nothing to relogin for this login user
}
UserGroupInformation.getLoginUser().reloginFromTicketCache(); Type guard
static boolean isTicketReloginable(UserGroupInformation ugi) {
return ugi.getAuthenticationMethod()
== UserGroupInformation.AuthenticationMethod.KERBEROS
&& !ugi.isFromKeytab();
} Try / catch
try {
ugi.reloginFromTicketCache();
} catch (KerberosAuthException e) {
if (e.getMessage().contains("login must be done first")) {
ugi = UserGroupInformation.loginUserFromTicketCache();
} else { throw e; }
} Prevention
- kinit before starting processes that will relogin from ticket cache
- Check isLoginTicketBased() before scheduling ticket relogin
- Re-login from scratch when a login context is unavailable
When it happens
Trigger: Calling ugi.reloginFromTicketCache() on a UGI not produced by loginUserFromTicketCache - e.g., a deserialized/copied login UGI, or one whose authentication method was switched to KERBEROS after simple login.
Common situations: Code that grabs getLoginUser() before Kerberos was enabled and later calls reloginFromTicketCache; UGI instances passed across process/task boundaries without their LoginContext.
Related errors
- Invalid attribute value for hadoop.kerberos.min.seconds.befo
- Illegal principal name " + name + ": " + ioe.toString()
- Failed to find user in name " + subject
- Problem with Kerberos auth_to_local name configuration
- Subject must not be null
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/df499d76e2c8ade9.
Report an issue: GitHub.