{"record":{"id":"3e7be8c80b66a722","repo":"apache/hadoop","slug":"tokenpath-already-exists","errorCode":null,"errorMessage":"${tokenPath} already exists","messagePattern":"(.+?) already exists","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/HistoryServerFileSystemStateStoreService.java","lineNumber":134,"sourceCode":"\n  @Override\n  public HistoryServerState loadState() throws IOException {\n    LOG.info(\"Loading history server state from \" + rootStatePath);\n    HistoryServerState state = new HistoryServerState();\n    loadTokenState(state);\n    return state;\n  }\n\n  @Override\n  public void storeToken(MRDelegationTokenIdentifier tokenId,\n      Long renewDate) throws IOException {\n    if (LOG.isDebugEnabled()) {\n      LOG.debug(\"Storing token \" + tokenId.getSequenceNumber());\n    }\n\n    Path tokenPath = getTokenPath(tokenId);\n    if (fs.exists(tokenPath)) {\n      throw new IOException(tokenPath + \" already exists\");\n    }\n\n    createNewFile(tokenPath, buildTokenData(tokenId, renewDate));\n  }\n\n  @Override\n  public void updateToken(MRDelegationTokenIdentifier tokenId,\n      Long renewDate) throws IOException {\n    if (LOG.isDebugEnabled()) {\n      LOG.debug(\"Updating token \" + tokenId.getSequenceNumber());\n    }\n\n    // Files cannot be atomically replaced, therefore we write a temporary\n    // update file, remove the original token file, then rename the update\n    // file to the token file. During recovery either the token file will be\n    // used or if that is missing and an update file is present then the\n    // update file is used.\n    Path tokenPath = getTokenPath(tokenId);","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-hs/src/main/java/org/apache/hadoop/mapreduce/v2/hs/HistoryServerFileSystemStateStoreService.java#L116-L152","documentation":"Thrown by the JobHistoryServer's filesystem-backed recovery state store when storeToken tries to persist a delegation token whose target file (TOKEN_FILE_PREFIX + sequence number, sharded into bucket directories) already exists on the backing FileSystem. The store is only active when mapreduce.jobhistory.recovery.enable=true and the filesystem state store is configured, so this indicates the store already holds state for the same token sequence number. It almost always means a stale, reused, or shared recovery-store directory rather than a code defect.","triggerScenarios":"JHS restarts with recovery enabled against a store directory that still contains a token file with the same sequence number; two JobHistoryServer processes pointed at the same mapreduce.jobhistory.recovery.store.fs.uri; token sequence numbering reset (fresh secret manager) while old token files remain in the store.","commonSituations":"Redeploying or reinstalling JHS without cleaning the recovery store; sharing one HDFS store location between two JHS instances (test/prod overlap); restoring a store from backup that already contains the tokens about to be re-stored.","solutions":["Verify exactly one active JobHistoryServer writes to the configured store URI (mapreduce.jobhistory.recovery.store.fs.uri).","If persisted token state is disposable, stop the JHS and remove/empty the recovery store directory; clients simply re-authenticate with newly issued tokens.","If state must be kept, list the bucket directories, locate the file named token_<sequence> from the message, and remove only that conflicting file.","Confirm mapreduce.jobhistory.recovery.enable / mapreduce.jobhistory.recovery.store.class are intentional and not left enabled from a previous test setup."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  store.storeToken(tokenId, renewDate);\n} catch (IOException e) {\n  if (e.getMessage().endsWith(\"already exists\")) {\n    // duplicate token state in the recovery store: remove stale file or treat as idempotent\n  } else {\n    throw e;\n  }\n}","preventionTips":["Run exactly one active JHS per recovery store location.","Clean or relocate the recovery store directory when rebuilding or redeploying JHS.","Always start JHS against the same recovery store so token sequence numbers stay monotonic."],"tags":["mapreduce","job-history-server","delegation-token","state-store","recovery"],"backgroundTag":"file-already-exists","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}