apache/hadoop · error · IllegalStateException
Subject does not contain a valid User
Error message
Subject does not contain a valid User
What it means
UserGroupInformation(Subject) takes the first User-class principal from the subject and requires it to exist with a non-null name. A Subject never produced by a Hadoop login is invalid here; note that a Subject with no User principal at all usually surfaces as NoSuchElementException from iterator().next() on the same line, while this IllegalStateException fires when a User principal exists but its name is null. Either way the Subject is not a Hadoop-populated one.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java:566
private void setLastLogin(long loginTime) {
user.setLastLogin(loginTime);
}
/**
* Create a UserGroupInformation for the given subject.
* This does not change the subject or acquire new credentials.
*
* The creator of subject is responsible for renewing credentials.
* @param subject the user's subject
*/
UserGroupInformation(Subject subject) {
this.subject = subject;
// do not access ANY private credentials since they are mutable
// during a relogin. no principal locking necessary since
// relogin/logout does not remove User principal.
this.user = subject.getPrincipals(User.class).iterator().next();
if (user == null || user.getName() == null) {
throw new IllegalStateException("Subject does not contain a valid User");
}
}
/**
* checks if logged in using kerberos
* @return true if the subject logged via keytab or has a Kerberos TGT
*/
public boolean hasKerberosCredentials() {
return user.getAuthenticationMethod() == AuthenticationMethod.KERBEROS;
}
/**
* Return the current user, including any doAs in the current stack.
* @return the current user
* @throws IOException if login fails
*/
@InterfaceAudience.Public
@InterfaceStability.EvolvingView on GitHub (pinned to 2add963021)
Solutions
- Use UserGroupInformation.getUGIFromSubject(subject) - it runs the Hadoop login modules that add the User principal
- Obtain UGIs from loginUserFromKeytab/loginUserFromTicketCache/getLoginUser which populate the User principal correctly
- For synthetic identities use createRemoteUser/createProxyUser, which build a well-formed Subject
Example fix
// before
Subject s = loginContext.getSubject();
UserGroupInformation ugi = new UserGroupInformation(s); // package-visible, fragile
// after
UserGroupInformation ugi =
UserGroupInformation.getUGIFromSubject(loginContext.getSubject()); Defensive patterns
Strategy: type-guard
Validate before calling
if (subject.getPrincipals(UserGroupInformation.User.class).isEmpty()) {
throw new IllegalArgumentException(
"subject lacks a User principal; use getUGIFromSubject/loginUserFromKeytab");
} Type guard
static boolean hasValidUserPrincipal(Subject subject) {
for (Principal p : subject.getPrincipals()) {
if (p instanceof UserGroupInformation.User
&& ((UserGroupInformation.User) p).getName() != null) {
return true;
}
}
return false;
} Prevention
- Never construct UserGroupInformation directly from a Subject you built yourself
- Route all subject wrapping through getUGIFromSubject or the loginUser* factories
- In tests, build subjects with createRemoteUser/createProxyUser
When it happens
Trigger: Directly constructing UserGroupInformation with a Subject built outside Hadoop - a raw JAAS login Subject holding only KerberosPrincipal, a Subject with just RealUser/principals, or a mock/test Subject with a null-named User.
Common situations: Integration tests assembling Subjects by hand; application code calling the package-visible constructor after an upgrade; SPNEGO filters wrapping non-Hadoop subjects.
Related errors
- Provided Subject must contain a KerberosPrincipal
- No URI in deserialized Path
- hadoop.security.authorizationis configured to true but servi
- Secure IO is not possible without native code extensions.
- File {f} already exists
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/d28f801e31554695.
Report an issue: GitHub.