{"record":{"id":"d28f801e31554695","repo":"apache/hadoop","slug":"subject-does-not-contain-a-valid-user","errorCode":null,"errorMessage":"Subject does not contain a valid User","messagePattern":"Subject does not contain a valid User","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java","lineNumber":566,"sourceCode":"  private void setLastLogin(long loginTime) {\n    user.setLastLogin(loginTime);\n  }\n\n  /**\n   * Create a UserGroupInformation for the given subject.\n   * This does not change the subject or acquire new credentials.\n   *\n   * The creator of subject is responsible for renewing credentials.\n   * @param subject the user's subject\n   */\n  UserGroupInformation(Subject subject) {\n    this.subject = subject;\n    // do not access ANY private credentials since they are mutable\n    // during a relogin.  no principal locking necessary since\n    // relogin/logout does not remove User principal.\n    this.user = subject.getPrincipals(User.class).iterator().next();\n    if (user == null || user.getName() == null) {\n      throw new IllegalStateException(\"Subject does not contain a valid User\");\n    }\n  }\n\n  /**\n   * checks if logged in using kerberos\n   * @return true if the subject logged via keytab or has a Kerberos TGT\n   */\n  public boolean hasKerberosCredentials() {\n    return user.getAuthenticationMethod() == AuthenticationMethod.KERBEROS;\n  }\n\n  /**\n   * Return the current user, including any doAs in the current stack.\n   * @return the current user\n   * @throws IOException if login fails\n   */\n  @InterfaceAudience.Public\n  @InterfaceStability.Evolving","sourceCodeStart":548,"sourceCodeEnd":584,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java#L548-L584","documentation":"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.","triggerScenarios":"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.","commonSituations":"Integration tests assembling Subjects by hand; application code calling the package-visible constructor after an upgrade; SPNEGO filters wrapping non-Hadoop subjects.","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"],"exampleFix":"// before\nSubject s = loginContext.getSubject();\nUserGroupInformation ugi = new UserGroupInformation(s); // package-visible, fragile\n// after\nUserGroupInformation ugi =\n    UserGroupInformation.getUGIFromSubject(loginContext.getSubject());","handlingStrategy":"type-guard","validationCode":"if (subject.getPrincipals(UserGroupInformation.User.class).isEmpty()) {\n  throw new IllegalArgumentException(\n      \"subject lacks a User principal; use getUGIFromSubject/loginUserFromKeytab\");\n}","typeGuard":"static boolean hasValidUserPrincipal(Subject subject) {\n  for (Principal p : subject.getPrincipals()) {\n    if (p instanceof UserGroupInformation.User\n        && ((UserGroupInformation.User) p).getName() != null) {\n      return true;\n    }\n  }\n  return false;\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["hadoop","security","ugi","jaas-subject"],"backgroundTag":"missing-user-principal","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}