{"record":{"id":"0feddcd6898ac862","repo":"apache/hadoop","slug":"security-enabled-but-user-not-authenticated-by-fil","errorCode":null,"errorMessage":"Security enabled but user not authenticated by filter","messagePattern":"Security enabled but user not authenticated by filter","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/JspHelper.java","lineNumber":125,"sourceCode":"   */\n  public static UserGroupInformation getUGI(ServletContext context,\n      HttpServletRequest request, Configuration conf,\n      final AuthenticationMethod secureAuthMethod,\n      final boolean tryUgiParameter) throws IOException {\n    UserGroupInformation ugi = null;\n    final String usernameFromQuery = getUsernameFromQuery(request, tryUgiParameter);\n    final String doAsUserFromQuery = request.getParameter(DoAsParam.NAME);\n    final String remoteUser;\n   \n    if (UserGroupInformation.isSecurityEnabled()) {\n      remoteUser = request.getRemoteUser();\n      final String tokenString = request.getParameter(DELEGATION_PARAMETER_NAME);\n      if (tokenString != null) {\n\n        // user.name, doas param is ignored in the token-based auth\n        ugi = getTokenUGI(context, request, tokenString, conf);\n      } else if (remoteUser == null) {\n        throw new IOException(\n            \"Security enabled but user not authenticated by filter\");\n      }\n    } else {\n      // Security's not on, pull from url or use default web user\n      remoteUser = (usernameFromQuery == null)\n          ? getDefaultWebUserName(conf) // not specified in request\n          : usernameFromQuery;\n    }\n\n    if (ugi == null) { // security is off, or there's no token\n      ugi = UserGroupInformation.createRemoteUser(remoteUser);\n      if (UserGroupInformation.isSecurityEnabled()) {\n        // This is not necessarily true, could have been auth'ed by user-facing\n        // filter\n        ugi.setAuthenticationMethod(secureAuthMethod);\n      }\n      if (doAsUserFromQuery != null && !doAsUserFromQuery.equals(remoteUser)) {\n        // create and attempt to authorize a proxy user","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/JspHelper.java#L107-L143","documentation":"In JspHelper.getUGI, when UserGroupInformation.isSecurityEnabled() is true the code requires either a delegation token parameter (DELEGATION_PARAMETER_NAME) or a non-null request.getRemoteUser(). If neither is present it throws IOException('Security enabled but user not authenticated by filter') — remoteUser is only populated when the hadoop-auth (SPNEGO/Kerberos) authentication filter ran successfully in front of the servlet. The exception therefore means the request reached the JSP layer anonymous.","triggerScenarios":"Kerberized cluster, request to a NameNode/DataNode web UI JSP that carries no delegation token and no Negotiate authentication, so request.getRemoteUser() is null: direct curl/browser access without SPNEGO, a filter chain that does not cover the hit path, or SPNEGO misconfiguration where the auth filter fails and passes the request through unauthenticated.","commonSituations":"curl or a browser without SPNEGO hitting secured JSPs; hadoop.http.authentication.* principal/keytab/type misconfigured so the filter never authenticates; custom or moved servlet paths added outside the authentication filter's URL mappings; health-check scripts that assume anonymous access like in non-secured clusters.","solutions":["Authenticate: kinit then use 'curl --negotiate -u :' or a SPNEGO-configured browser","Or pass a delegation token via the delegation parameter, obtained through WebHDFS GETDELEGATIONTOKEN","Verify hadoop.http.authentication.type=kerberos and that hadoop.http.authentication.kerberos.principal/keytab are correct so the filter actually challenges anonymous requests","Confirm the requested URL is served through the filter-protected endpoint (not a port or path that bypasses the authentication filter chain)"],"exampleFix":"# before (anonymous, throws)\ncurl http://nn:9870/browseBlock.jsp?... \n\n# after (SPNEGO)\nkinit alice@EXAMPLE.COM && curl --negotiate -u : 'http://nn:9870/browseBlock.jsp?...'","handlingStrategy":"validation","validationCode":"if (UserGroupInformation.isSecurityEnabled()\n    && request.getParameter(DelegationParam.NAME) == null\n    && request.getRemoteUser() == null) {\n  resp.setHeader(\"WWW-Authenticate\", \"Negotiate\");\n  resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, \"Authenticate\");\n  return; // never reach JspHelper.getUGI anonymous\n}","typeGuard":null,"tryCatchPattern":"try {\n  ugi = JspHelper.getUGI(context, request, conf);\n} catch (IOException e) {\n  if (\"Security enabled but user not authenticated by filter\".equals(e.getMessage())) {\n    resp.setHeader(\"WWW-Authenticate\", \"Negotiate\");\n    resp.sendError(401, \"Kerberos authentication required\");\n  } else throw e;\n}","preventionTips":["Verify the hadoop-auth filter covers every servlet/JSP path that calls getUGI (filter-mapping URL patterns)","Keep SPNEGO principal/keytab configs valid and monitor filter startup for auth errors","Health checks against secured UIs must use --negotiate or delegation tokens, never anonymous GETs"],"tags":["hdfs","web-ui","kerberos","spnego","authentication","security"],"backgroundTag":"request-not-authenticated","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}