{"record":{"id":"024c6f71e93a4534","repo":"apache/hadoop","slug":"mr-am-not-authorized-to-issue-delegation-token","errorCode":null,"errorMessage":"MR AM not authorized to issue delegation token","messagePattern":"MR AM not authorized to issue delegation token","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/client/MRClientService.java","lineNumber":424,"sourceCode":"      Collection<Task> tasks = job.getTasks(taskType).values();\n      LOG.info(\"Getting task report for \" + taskType + \"   \" + jobId\n          + \". Report-size will be \" + tasks.size());\n\n      // Take lock to allow only one call, otherwise heap will blow up because\n      // of counters in the report when there are multiple callers.\n      synchronized (getTaskReportsLock) {\n        for (Task task : tasks) {\n          response.addTaskReport(task.getReport());\n        }\n      }\n\n      return response;\n    }\n\n    @Override\n    public GetDelegationTokenResponse getDelegationToken(\n        GetDelegationTokenRequest request) throws IOException {\n      throw new IOException(\"MR AM not authorized to issue delegation\" +\n      \t\t\" token\");\n    }\n\n    @Override\n    public RenewDelegationTokenResponse renewDelegationToken(\n        RenewDelegationTokenRequest request) throws IOException {\n      throw new IOException(\"MR AM not authorized to renew delegation\" +\n          \" token\");\n    }\n\n    @Override\n    public CancelDelegationTokenResponse cancelDelegationToken(\n        CancelDelegationTokenRequest request) throws IOException {\n      throw new IOException(\"MR AM not authorized to cancel delegation\" +\n          \" token\");\n    }\n  }\n","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-app/src/main/java/org/apache/hadoop/mapreduce/v2/app/client/MRClientService.java#L406-L442","documentation":"MRClientService.getDelegationToken unconditionally throws this IOException: the MR ApplicationMaster never issues delegation tokens. Token issuance is a JobHistoryServer capability (HSClientService implements getDelegationToken for the history service); the AM only authorizes via job ACLs plus Kerberos. Any client that follows the generic MRClientProtocol token path against the AM endpoint gets rejected by design.","triggerScenarios":"Client calls protocol.getDelegationToken(GetDelegationTokenRequest) on the AM tracking address; token-renewal-aware wrappers (e.g., long-lived proxy users) automatically request a DT from every MR protocol endpoint they touch.","commonSituations":"Porting MRv1-era clients that fetched job tokens from the JobTracker; Oozie/secure-proxy style code requesting DTs before reading job status; hitting the AM instead of the JHS because both speak MRClientProtocol.","solutions":["Point the token request at the Job History Server (historyServiceAddress from the job or mapreduce.jobhistory.address) which does issue tokens","Skip DT acquisition for AM calls and authenticate with Kerberos instead — the AM's verifyAndGetJob path only needs an authenticated UGI plus job ACLs","If you must act for another user, use the doAs/proxy pattern on a Kerberos-authenticated connection rather than a delegation token"],"exampleFix":"// before - asking the ApplicationMaster\nGetDelegationTokenResponse resp = amProtocol.getDelegationToken(req);\n\n// after - ask the Job History Server, which implements token issuance\nGetDelegationTokenResponse resp = hsProtocol.getDelegationToken(req);","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  token = protocol.getDelegationToken(new GetDelegationTokenRequest()).getDelegationToken();\n} catch (IOException e) {\n  if (e.getMessage().contains(\"not authorized to issue delegation token\")) {\n    token = null; // AM never issues DTs: fall back to Kerberos auth or JHS\n  } else { throw e; }\n}","preventionTips":["Request MR delegation tokens only from the JobHistoryServer endpoint","Authenticate AM calls with Kerberos instead of delegation tokens","Check token.getService() before running generic token-acquisition code against an MR protocol handle"],"tags":["mapreduce","delegation-token","security","application-master"],"backgroundTag":"delegation-token-unsupported","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}