{"record":{"id":"6ba8e0b38a73e02c","repo":"apache/hadoop","slug":"cannot-rollback-to-storage-version-prevstorage-ge","errorCode":null,"errorMessage":"Cannot rollback to storage version {prevStorage.getLayoutVersion()} using this version of the NameNode, which uses storage version {targetLayoutVersion}. Please use the previous version of HDFS to perform the rollback.","messagePattern":"Cannot rollback to storage version (.+?) using this version of the NameNode, which uses storage version (.+?)\\. Please use the previous version of HDFS to perform the rollback\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NNUpgradeUtil.java","lineNumber":70,"sourceCode":"   * @return true if this JM can roll back, false otherwise.\n   * @throws IOException in the event of error\n   */\n  static boolean canRollBack(StorageDirectory sd, StorageInfo storage,\n      StorageInfo prevStorage, int targetLayoutVersion) throws IOException {\n    File prevDir = sd.getPreviousDir();\n    if (!prevDir.exists()) {  // use current directory then\n      LOG.info(\"Storage directory \" + sd.getRoot()\n               + \" does not contain previous fs state.\");\n      // read and verify consistency with other directories\n      storage.readProperties(sd);\n      return false;\n    }\n\n    // read and verify consistency of the prev dir\n    prevStorage.readPreviousVersionProperties(sd);\n\n    if (prevStorage.getLayoutVersion() != targetLayoutVersion) {\n      throw new IOException(\n        \"Cannot rollback to storage version \" +\n        prevStorage.getLayoutVersion() +\n        \" using this version of the NameNode, which uses storage version \" +\n        targetLayoutVersion + \". \" +\n        \"Please use the previous version of HDFS to perform the rollback.\");\n    }\n    \n    return true;\n  }\n\n  /**\n   * Finalize the upgrade. The previous dir, if any, will be renamed and\n   * removed. After this is completed, rollback is no longer allowed.\n   * \n   * @param sd the storage directory to finalize\n   * @throws IOException in the event of error\n   */\n  static void doFinalize(StorageDirectory sd) throws IOException {","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NNUpgradeUtil.java#L52-L88","documentation":"Thrown by NNUpgradeUtil.doRollback when the layout version recorded in the storage directory's 'previous' directory does not equal targetLayoutVersion, the layout version implemented by the running NameNode binary. HDFS changes its on-disk storage layout between releases, so a rollback must be executed by the exact software version that wrote the 'previous' snapshot. This check refuses the rollback instead of corrupting metadata with an incompatible reader/writer.","triggerScenarios":"Running 'hdfs namenode -rollback' (or starting the NN with -rollback) after doPreUpgrade/upgrade when prevStorage.readPreviousVersionProperties(sd) reports a layoutVersion different from the current binary's targetLayoutVersion. Typical when binaries were swapped again after the upgrade, so the installed software no longer matches the version that created 'previous'.","commonSituations":"Upgraded 3.3.x -> 3.4.x, then downgraded binaries further before rolling back; attempting rollback with a different vendor distribution than the one that upgraded the cluster; a stale 'previous' directory left over from an older upgrade cycle.","solutions":["Reinstall the exact Hadoop/HDFS distribution that performed the upgrade (the one that created the 'previous' directory) and run 'hdfs namenode -rollback' with it on every NameNode/storage directory.","If you no longer want to roll back, finalize instead: 'hdfs dfsadmin -finalizeUpgrade' removes the incompatible 'previous' directory.","Before retrying, compare layoutVersion in the VERSION file under the 'previous' dir with the layout version of the installed software (checked in on startup) to confirm which build you need.","If the previous state is unusable and rollback is impossible, restore the namespace from a checkpoint/backup or reformat (data loss - last resort)."],"exampleFix":"// before\nhdfs namenode -rollback   # run with newer binaries than the ones that wrote 'previous'\n\n// after\n# identify the layout the rollback target uses\ngrep layoutVersion /data/dfs/name/previous/VERSION\n# run the rollback with the exact pre-upgrade Hadoop distribution\n<extract that distribution and put it on PATH>\nhdfs namenode -rollback","handlingStrategy":"validation","validationCode":"# before issuing 'hdfs namenode -rollback', verify the previous layout matches the installed software\nprev=$(grep '^layoutVersion' /data/dfs/name/previous/VERSION 2>/dev/null | cut -d= -f2)\nif [ -z \"$prev\" ]; then echo \"no previous dir - nothing to roll back\"; exit 0; fi\nif [ \"$prev\" != \"$(hdfs namenode -metadataVersion 2>/dev/null | awk '/layoutVersion/ {print $NF}')\" ]; then\n  echo \"layout mismatch: previous=$prev - use the Hadoop version that wrote 'previous'\"\n  exit 1\nfi\nhdfs namenode -rollback","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the pre-upgrade Hadoop distribution installed (or its tarball archived) on every NN host until the upgrade is finalized.","Always finalize ('hdfs dfsadmin -finalizeUpgrade') after the commit window so a stale incompatible 'previous' dir can never collide with a later rollback.","Document the exact distribution/version used for each upgrade so the rollback binary is unambiguous."],"tags":["hdfs","namenode","upgrade","rollback","layout-version","storage"],"backgroundTag":"hdfs-rollback-version-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}