{"record":{"id":"f70599a8267ecbf7","repo":"apache/hadoop","slug":"invalid-volume","errorCode":"INVALID_VOLUME","errorMessage":"Disk Balancer - Unable to find source volume: {}. SubmitPlan failed.","messagePattern":"Disk Balancer - Unable to find source volume: (.+?)\\. SubmitPlan failed\\.","errorType":"exception","errorClass":"DiskBalancerException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DiskBalancer.java","lineNumber":530,"sourceCode":"   */\n  private void createWorkPlan(NodePlan plan) throws DiskBalancerException {\n    Preconditions.checkState(lock.isHeldByCurrentThread());\n\n    // Cleanup any residual work in the map.\n    workMap.clear();\n    Map<String, String> storageIDToVolBasePathMap =\n        getStorageIDToVolumeBasePathMap();\n\n    for (Step step : plan.getVolumeSetPlans()) {\n      String sourceVolUuid = step.getSourceVolume().getUuid();\n      String destVolUuid = step.getDestinationVolume().getUuid();\n\n      String sourceVolBasePath = storageIDToVolBasePathMap.get(sourceVolUuid);\n      if (sourceVolBasePath == null) {\n        final String errMsg = \"Disk Balancer - Unable to find source volume: \"\n            + step.getSourceVolume().getPath() + \". SubmitPlan failed.\";\n        LOG.error(errMsg);\n        throw new DiskBalancerException(errMsg,\n            DiskBalancerException.Result.INVALID_VOLUME);\n      }\n\n      String destVolBasePath = storageIDToVolBasePathMap.get(destVolUuid);\n      if (destVolBasePath == null) {\n        final String errMsg = \"Disk Balancer - Unable to find dest volume: \"\n            + step.getDestinationVolume().getPath() + \". SubmitPlan failed.\";\n        LOG.error(errMsg);\n        throw new DiskBalancerException(errMsg,\n            DiskBalancerException.Result.INVALID_VOLUME);\n      }\n      VolumePair volumePair = new VolumePair(sourceVolUuid,\n          sourceVolBasePath, destVolUuid, destVolBasePath);\n      createWorkPlan(volumePair, step);\n    }\n  }\n\n  /**","sourceCodeStart":512,"sourceCodeEnd":548,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DiskBalancer.java#L512-L548","documentation":"While translating plan steps into DiskBalancerWorkItems, createWorkPlan() resolves each step's source volume UUID against the DataNode's live storageID-to-volume map (getStorageIDToVolumeBasePathMap()). If the source volume UUID is absent, the plan references storage that no longer exists on this node, and Result.INVALID_VOLUME is thrown with the missing volume's path in the message.","triggerScenarios":"submitPlan where a step's sourceVolumeUUID is not among the DataNode's current volumes: a disk was removed, failed, or replaced between `-plan` and `-execute`; the plan was generated against a different node's volume set; storage IDs changed after a reformat.","commonSituations":"Dead disk swapped out before the plan was executed; hot-removed volume; DataNode restarted with a reduced dfs.datanode.data.dir list; submitting a plan file that belongs to another machine.","solutions":["Regenerate the plan so it reflects the current volume set, then submit.","List the DataNode's current volumes (DataNode JMX FSDatasetStateInfo, `hdfs dfsadmin -report`) and confirm each step's source volume UUID still exists.","If a volume was intentionally removed, discard the old plan — it cannot be patched by hand without breaking the plan hash.","Verify the plan is being submitted to the same DataNode it was generated for."],"exampleFix":"// before: submit a plan generated before a disk was replaced\ndiskBalancer.submitPlan(planID, version, planString, false);\n\n// after: check every step's volumes against the live volume set first\nMap<String, ?> volumes = dataset.getVolumeInfoMap(); // keyed by storageID\nfor (Step s : NodePlan.parseJson(planString).getVolumeSetPlans()) {\n  if (!volumes.containsKey(s.getSourceVolume().getUuid())) {\n    planString = generateFreshPlan(datanode); // volume set changed\n    break;\n  }\n}\ndiskBalancer.submitPlan(planID, version, planString, false);","handlingStrategy":"validation","validationCode":"Map<String, ?> volumes = dataset.getVolumeInfoMap(); // storageID -> VolumeInfo\nfor (Step s : NodePlan.parseJson(planString).getVolumeSetPlans()) {\n  if (!volumes.containsKey(s.getSourceVolume().getUuid())) {\n    // a source volume no longer exists: regenerate the plan\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  diskBalancer.submitPlan(planID, version, plan, false);\n} catch (DiskBalancerException e) {\n  if (e.getResult() == DiskBalancerException.Result.INVALID_VOLUME\n      && e.getMessage().contains(\"source volume\")) {\n    // volume set changed since planning: regenerate the plan\n  }\n}","preventionTips":["Regenerate plans whenever disks are added, removed, or replaced","Compare plan step volume UUIDs against DataNode JMX volume state before executing","Execute plans on the same node and volume configuration they were generated against"],"tags":["disk-balancer","volume","storage-id","hdfs","datanode"],"backgroundTag":"volume-not-found","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}