{"record":{"id":"850144a67052d478","repo":"apache/hadoop","slug":"fatal-unauthorized","errorCode":"FATAL_UNAUTHORIZED","errorMessage":"\"Authenticated user (\" + user + \") doesn't match what the client claims to be (\" + protocolUser + \")\"","messagePattern":"\"Authenticated user \\(\" \\+ user \\+ \"\\) doesn't match what the client claims to be \\(\" \\+ protocolUser \\+ \"\\)\"","errorType":"exception","errorClass":"FatalRpcServerException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java","lineNumber":2771,"sourceCode":"      }\n      connectionContext = getMessage(IpcConnectionContextProto.getDefaultInstance(), buffer);\n      protocolName = connectionContext.hasProtocol() ? connectionContext\n          .getProtocol() : null;\n\n      UserGroupInformation protocolUser = ProtoUtil.getUgi(connectionContext);\n      if (authProtocol == AuthProtocol.NONE) {\n        user = protocolUser;\n      } else {\n        // user is authenticated\n        user.setAuthenticationMethod(authMethod);\n        //Now we check if this is a proxy user case. If the protocol user is\n        //different from the 'user', it is a proxy user scenario. However, \n        //this is not allowed if user authenticated with DIGEST.\n        if ((protocolUser != null)\n            && (!protocolUser.getUserName().equals(user.getUserName()))) {\n          if (authMethod == AuthMethod.TOKEN) {\n            // Not allowed to doAs if token authentication is used\n            throw new FatalRpcServerException(\n                RpcErrorCodeProto.FATAL_UNAUTHORIZED,\n                new AccessControlException(\"Authenticated user (\" + user\n                    + \") doesn't match what the client claims to be (\"\n                    + protocolUser + \")\"));\n          } else {\n            // Effective user can be different from authenticated user\n            // for simple auth or kerberos auth\n            // The user is the real user. Now we create a proxy user\n            UserGroupInformation realUser = user;\n            user = UserGroupInformation.createProxyUser(protocolUser\n                .getUserName(), realUser);\n          }\n        }\n      }\n      authorizeConnection();\n      // don't set until after authz because connection isn't established\n      connectionContextRead = true;\n      if (user != null) {","sourceCodeStart":2753,"sourceCodeEnd":2789,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/ipc/Server.java#L2753-L2789","documentation":"During connection-context processing, when the connection is authenticated (Kerberos or token) and the client's declared effective user differs from the authenticated user, the server treats it as proxying. Proxying is allowed for Kerberos/simple auth but forbidden for token (delegation token) authentication, so FATAL_UNAUTHORIZED with an AccessControlException is thrown. The message names both the authenticated user and the claimed (doAs) user.","triggerScenarios":"A client authenticates with a delegation token whose owner is userA but sets the connection context effective user to userB (doAs); frameworks calling UserGroupInformation.createProxyUser on top of a token-authenticated UGI; Oozie/Hive-style impersonation while holding a delegation token.","commonSituations":"Sqoop/Oozie/Hive jobs that proxy as the job owner while the connection was authenticated with a delegation token; application servers reusing a token-authenticated UGI and then switching effective users per request; misconfigured proxyuser settings where teams reach for tokens instead of Kerberos proxying.","solutions":["Drop the doAs: connect as the delegation token's owner (the effective user must equal the token owner)","If impersonation is required, authenticate with Kerberos as the real user and use UserGroupInformation.createProxyUser with proper hadoop.proxyuser.*.groups/hosts configuration instead of a token","Check which UGI the client proxy was built from (UserGroupInformation.getCurrentUser()) before creating the RPC proxy, and rebuild the proxy from the correct UGI","Audit middleware (Hive, Oozie, JDBC drivers) settings like hive.server2.proxy.user or doAs that inject an effective user on token connections"],"exampleFix":"// before: token-authenticated ugi, proxying as someone else\nUserGroupInformation tokenUgi = UserGroupInformation.createRemoteUser(tokenOwner);\nUserGroupInformation proxy = UserGroupInformation.createProxyUser(\"otheruser\", tokenUgi);\nproxy.doAs(action); // throws: token auth cannot doAs\n\n// after: either use the token owner directly...\ntokenUgi.doAs(action);\n// ...or authenticate with Kerberos and configure proxyuser for the real user","handlingStrategy":"validation","validationCode":"// before building the proxy on a token-authenticated UGI, assert no doAs mismatch\nUserGroupInformation current = UserGroupInformation.getCurrentUser();\nif (current.getAuthenticationMethod() == AuthMethod.TOKEN\n    && !current.getShortUserName().equals(effectiveUser)) {\n  throw new IllegalArgumentException(\n      \"Cannot doAs '\" + effectiveUser + \"' with a delegation token owned by \"\n      + current.getShortUserName() + \"; use the token owner or Kerberos proxying\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  proxy.doSomething();\n} catch (RemoteException re) {\n  if (re.getClassName().contains(\"AccessControlException\")\n      && re.getMessage().contains(\"doesn't match what the client claims\")) {\n    // reconnect without doAs, or re-authenticate with Kerberos for proxying\n  } else { throw re; }\n}","preventionTips":["Never pair delegation-token auth with an effective user different from the token owner","For impersonation, authenticate with Kerberos and configure hadoop.proxyuser.<realuser>.hosts/groups","Log UserGroupInformation.getCurrentUser() + auth method before creating RPC proxies in integration code"],"tags":["authorization","delegation-token","proxy-user","security","hadoop-ipc"],"backgroundTag":"proxy-user-unauthorized","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}