{"record":{"id":"41b1151c6babee80","repo":"apache/hadoop","slug":"mr-am-not-authorized-to-cancel-delegation-token","errorCode":null,"errorMessage":"MR AM not authorized to cancel delegation token","messagePattern":"MR AM not authorized to cancel 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":438,"sourceCode":"\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;\n  }\n\n  protected ResourceConfig configure() {\n    ResourceConfig config = new ResourceConfig();\n    config.register(new JerseyBinder());\n    config.register(AMWebServices.class);\n    config.register(GenericExceptionHandler.class);","sourceCodeStart":420,"sourceCodeEnd":456,"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#L420-L456","documentation":"MRClientService.cancelDelegationToken unconditionally throws for the same reason as get/renew: the AM never mints delegation tokens, so cancellation against the AM is a category error. Cancelling a valid JHS-issued token must be sent to the JobHistoryServer that issued it.","triggerScenarios":"Client calls protocol.cancelDelegationToken(CancelDelegationTokenRequest) on the AM tracking address; cleanup code iterates credentials and cancels each token via whichever MR protocol handle is open.","commonSituations":"Session cleanup code shared between JHS and AM handles; test harnesses pointing every MR operation at the first protocol stub they created.","solutions":["Route cancellation to the issuing JobHistoryServer (HSClientProtocol), matching token.getService()","If the operation came from generic token-cleanup code, gate it on token.getKind()/service instead of the protocol type","Treat this IOException from the AM as non-fatal — the token was never valid against the AM anyway"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  token.cancel(conf);\n} catch (IOException e) {\n  if (e.getMessage().contains(\"not authorized to cancel delegation token\")) {\n    // token was never valid against the AM; cancel at issuing JHS if needed\n  } else { throw e; }\n}","preventionTips":["Cancel tokens at the service that issued them","Gate cleanup code on token kind/service rather than protocol type","Treat AM-side cancel errors as non-fatal in session teardown"],"tags":["mapreduce","delegation-token","cancellation","security"],"backgroundTag":"delegation-token-unsupported","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}