{"record":{"id":"2fe722aa97bbcd46","repo":"apache/hadoop","slug":"mr-am-not-authorized-to-renew-delegation-token","errorCode":null,"errorMessage":"MR AM not authorized to renew delegation token","messagePattern":"MR AM not authorized to renew 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":431,"sourceCode":"        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\n  public KillTaskAttemptResponse forceKillTaskAttempt(\n      KillTaskAttemptRequest request) throws YarnException, IOException {\n    return protocolHandler.killTaskAttempt(request);\n  }\n\n  public WebApp getWebApp() {\n    return webApp;","sourceCodeStart":413,"sourceCodeEnd":449,"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#L413-L449","documentation":"MRClientService.renewDelegationToken unconditionally throws: the MR ApplicationMaster is not a token issuer, so it has nothing to renew. Renewal is only meaningful against the service that created the token (JobHistoryServer / RM as appropriate). Because the AM's MRClientProtocol shares the wire protocol with the JHS, generic renewal code can reach this method by mistake.","triggerScenarios":"Client-side Token.renew() invoked with the AM's service principal/address (the token's service field resolves to the AM); a delegation-renewal thread walking all MR endpoints renews against the AM.","commonSituations":"Long-running clients that renew every collected token in one loop without checking which service issued it; misconfigured mapreduce.jobhistory.address causing the client to fall back to the AM endpoint.","solutions":["Renew only against the issuing service — tokens from the JHS carry the JHS address; print token.getService() to confirm where renewal must go","Verify mapreduce.jobhistory.address / mapreduce.jobhistory.webapp.address resolve to the real JobHistoryServer","Catch this IOException in renewal loops and skip AM-issued endpoints instead of failing the whole renewal pass"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  token.renew(conf);\n} catch (IOException e) {\n  if (e.getMessage().contains(\"not authorized to renew delegation token\")) {\n    skipEndpoint(); // AM is not the issuer; renew via the issuing JHS instead\n  } else { throw e; }\n}","preventionTips":["Renew each token against its issuing service (token.getService()), never against an arbitrary MR endpoint","Keep mapreduce.jobhistory.address correct so renewal threads resolve the JHS","Exclude AM-protocol stubs from generic renewal loops"],"tags":["mapreduce","delegation-token","renewal","security"],"backgroundTag":"delegation-token-unsupported","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}