{"record":{"id":"cfb6870a1b7a9502","repo":"apache/hadoop","slug":"usernames-not-matched-expecting-null-but-name-na","errorCode":null,"errorMessage":"Usernames not matched: expecting null but name={name}","messagePattern":"Usernames not matched: expecting null but name=(.+?)","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":211,"sourceCode":"      final String clientAddr = proxyHeader.split(\",\")[0].trim();\n      if (!clientAddr.isEmpty()) {\n        remoteAddr = clientAddr;\n      }\n    }\n    return remoteAddr;\n  }\n\n  public static int getRemotePort(HttpServletRequest request) {\n    return request.getRemotePort();\n  }\n\n  /**\n   * Expected user name should be a short name.\n   */\n  public static void checkUsername(final String expected, final String name\n      ) throws IOException {\n    if (expected == null && name != null) {\n      throw new IOException(\"Usernames not matched: expecting null but name=\"\n          + name);\n    }\n    if (name == null) { //name is optional, null is okay\n      return;\n    }\n    KerberosName u = new KerberosName(name);\n    String shortName = u.getShortName();\n    if (!shortName.equals(expected)) {\n      throw new IOException(\"Usernames not matched: name=\" + shortName\n          + \" != expected=\" + expected);\n    }\n  }\n\n  private static String getUsernameFromQuery(final HttpServletRequest request,\n      final boolean tryUgiParameter) {\n    String username = request.getParameter(UserParam.NAME);\n    if (username == null && tryUgiParameter) {\n      //try ugi parameter","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/JspHelper.java#L193-L229","documentation":"JspHelper.checkUsername(expected, name) throws IOException('Usernames not matched: expecting null but name=...') when expected == null but name != null. Its production caller is DataNodeUGIProvider (DataNodeUGIProvider.java:146), which passes the token-derived UGI short name as 'expected' and the user.name query parameter as 'name': a request that supplies user.name while the authenticated identity produced no username is rejected as a mismatch rather than trusted.","triggerScenarios":"Secured DataNode WebHDFS request where a delegation token's owner resolves to a null/empty short username while the request URL also carries a user.name parameter (the token path deliberately ignores user.name, so any residual name with a nameless identity trips this check).","commonSituations":"Malformed or truncated delegation token string in the URL; token minted for a principal whose auth_to_local mapping yields an empty name; client libraries that always append user.name to DataNode URLs.","solutions":["Drop the user.name parameter from the request — under security the token identity is authoritative","Obtain and pass a fresh, valid delegation token (WebHDFS GETDELEGATIONTOKEN) and verify its owner field is populated","If tokens systematically resolve to empty owners, review auth_to_local / hadoop.security.auth_to_local rules for the issuing principal"],"exampleFix":"# before (token with empty owner + explicit user)\ncurl 'http://dn:9864/webhdfs/v1/f?op=OPEN&delegation=<token>&user.name=alice'\n\n# after (token identity only)\ncurl 'http://dn:9864/webhdfs/v1/f?op=OPEN&delegation=<token>'","handlingStrategy":"try-catch","validationCode":"UserGroupInformation tokenUgi = getUgiFromToken(tokenString); // DataNodeUGIProvider path\nString fromQuery = request.getParameter(UserParam.NAME);\nif (tokenUgi != null && tokenUgi.getShortUserName() == null && fromQuery != null) {\n  resp.sendError(403, \"user.name supplied but token identity has no username\");\n  return;\n}\nJspHelper.checkUsername(tokenUgi.getShortUserName(), fromQuery);","typeGuard":null,"tryCatchPattern":"try {\n  JspHelper.checkUsername(expected, name);\n} catch (IOException e) {\n  if (e.getMessage().startsWith(\"Usernames not matched: expecting null\")) {\n    resp.sendError(403, \"user.name parameter conflicts with token identity\");\n  } else throw e;\n}","preventionTips":["Never append user.name to secured DataNode WebHDFS URLs — the token identity is authoritative","Validate delegation tokens are complete (not truncated by URL length limits or encoding)","Fail fast when a token's owner resolves to an empty short name"],"tags":["hdfs","webhdfs","datanode","delegation-token","ugi","username-mismatch"],"backgroundTag":"username-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}