{"record":{"id":"8b0e36c20611fbbb","repo":"apache/hadoop","slug":"request-ugi-cannot-be-null","errorCode":null,"errorMessage":"request UGI cannot be NULL","messagePattern":"request UGI cannot be NULL","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/web/DelegationTokenAuthenticationHandler.java","lineNumber":270,"sourceCode":"              : null;\n          // Create the proxy user if doAsUser exists\n          String doAsUser = DelegationTokenAuthenticationFilter.getDoAs(request);\n          if (requestUgi != null && doAsUser != null) {\n            requestUgi = UserGroupInformation.createProxyUser(\n                doAsUser, requestUgi);\n            try {\n              ProxyUsers.authorize(requestUgi, request.getRemoteAddr());\n            } catch (AuthorizationException ex) {\n              HttpExceptionUtils.createServletExceptionResponse(response,\n                  HttpServletResponse.SC_FORBIDDEN, ex);\n              return false;\n            }\n          }\n          Map map = null;\n          switch (dtOp) {\n            case GETDELEGATIONTOKEN:\n              if (requestUgi == null) {\n                throw new IllegalStateException(\"request UGI cannot be NULL\");\n              }\n              String renewer = ServletUtils.getParameter(request,\n                  KerberosDelegationTokenAuthenticator.RENEWER_PARAM);\n              String service = ServletUtils.getParameter(request,\n                  KerberosDelegationTokenAuthenticator.SERVICE_PARAM);\n              try {\n                Token<?> dToken = tokenManager.createToken(requestUgi, renewer,\n                    service);\n                map = delegationTokenToJSON(dToken);\n              } catch (IOException ex) {\n                throw new AuthenticationException(ex.toString(), ex);\n              }\n              break;\n            case RENEWDELEGATIONTOKEN:\n              if (requestUgi == null) {\n                throw new IllegalStateException(\"request UGI cannot be NULL\");\n              }\n              String tokenToRenew = ServletUtils.getParameter(request,","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/web/DelegationTokenAuthenticationHandler.java#L252-L288","documentation":"Server side of the HTTP delegation-token API. After the authentication handler runs, managementOperation expects the request UGI (the authenticated end-user identity) to be attached to the request. For GETDELEGATIONTOKEN it must be non-null because a token can only be minted for a real authenticated user; null triggers IllegalStateException \"request UGI cannot be NULL\", which HttpExceptionUtils converts into an HTTP 500.","triggerScenarios":"A GETDELEGATIONTOKEN request arrives with requestUgi == null: anonymous access was permitted (simple auth with anonymous allowed) and no user was established, or a custom AuthenticationHandler/DelegationTokenAuthenticationHandler subclass failed to set the DELEGATION_TOKEN_UGI request attribute in its authenticate() before delegating.","commonSituations":"curl-ing the token endpoint without a user.name parameter while hadoop.http.authentication.simple.anonymous.allowed=true; custom auth handler integrations (header-based SSO frontends) that skip setting the UGI attribute; spnego fallback to anonymous.","solutions":["Authenticate the request: use Kerberos/SPNEGO, or with simple auth supply ?user.name=<user> and set hadoop.http.authentication.simple.anonymous.allowed=false.","If you run a custom handler, set the request UGI attribute in authenticate() (mirror PseudoDelegationTokenAuthenticationHandler) before returning the AuthenticationToken.","As the client, retry only after establishing real credentials - retrying anonymous always reproduces the 500."],"exampleFix":"// before (server, custom handler)\npublic AuthenticationToken authenticate(HttpServletRequest req, HttpServletResponse rsp) { return token; }\n// after: attach the UGI the DT handler expects\npublic AuthenticationToken authenticate(HttpServletRequest req, HttpServletResponse rsp) {\n  AuthenticationToken token = ...;\n  UserGroupInformation ugi = UserGroupInformation.createRemoteUser(token.getUserName());\n  req.setAttribute(DelegationTokenAuthenticatedURL.DELEGATION_TOKEN_UGI_ATTRIBUTE, ugi);\n  return token;\n}","handlingStrategy":"validation","validationCode":"// Server-side (filter init): anonymous access + token ops is a misconfiguration\nif (\"simple\".equals(conf.get(\"hadoop.http.authentication.type\"))\n    && conf.getBoolean(\"hadoop.http.authentication.simple.anonymous.allowed\", true)) {\n  LOG.warn(\"anonymous requests reaching token ops will 500; disable anonymous access\");\n}\n// Client-side: establish identity before requesting a token\nUserGroupInformation ugi = UserGroupInformation.getLoginUser();\nPreconditions.checkState(ugi.getRealUser() != null || !ugi.isAnonymous(),\n    \"authenticate (Kerberos or user.name) before GETDELEGATIONTOKEN\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set hadoop.http.authentication.simple.anonymous.allowed=false when token operations are exposed.","Always negotiate Kerberos (or pass user.name under simple auth) before GETDELEGATIONTOKEN.","Custom auth handlers must set the DELEGATION_TOKEN_UGI request attribute like the built-in handlers do."],"tags":["http","authentication","delegation-token","ugi","anonymous-access"],"backgroundTag":"authentication-required","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}