apache/hadoop · error · DiskBalancerException
INVALID_MOVE
INVALID_MOVE
Error message
Disk Balancer - Source and destination volumes are same: {} What it means
createWorkPlan(VolumePair, Step) rejects a plan step whose source volume UUID equals its destination volume UUID with Result.INVALID_MOVE. Copying data from a volume to itself is a no-op, so such a step means the plan is degenerate — usually planner output on an unusual volume layout or a hand-crafted plan. Note it is logged at WARN but still aborts submitPlan.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DiskBalancer.java:609
blockMover.setRunnable();
blockMover.copyBlocks(entry.getKey(), entry.getValue());
}
}
});
}
/**
* Insert work items to work map.
* @param volumePair - VolumePair
* @param step - Move Step
*/
private void createWorkPlan(final VolumePair volumePair, Step step)
throws DiskBalancerException {
if (volumePair.getSourceVolUuid().equals(volumePair.getDestVolUuid())) {
final String errMsg = "Disk Balancer - Source and destination volumes " +
"are same: " + volumePair.getSourceVolUuid();
LOG.warn(errMsg);
throw new DiskBalancerException(errMsg,
DiskBalancerException.Result.INVALID_MOVE);
}
long bytesToMove = step.getBytesToMove();
// In case we have a plan with more than
// one line of same VolumePair
// we compress that into one work order.
if (workMap.containsKey(volumePair)) {
bytesToMove += workMap.get(volumePair).getBytesToCopy();
}
DiskBalancerWorkItem work = new DiskBalancerWorkItem(bytesToMove, 0);
// all these values can be zero, if so we will use
// values from configuration.
work.setBandwidth(step.getBandwidth());
work.setTolerancePercent(step.getTolerancePercent());
work.setMaxDiskErrors(step.getMaxDiskErrors());
workMap.put(volumePair, work);View on GitHub (pinned to 2add963021)
Solutions
- Regenerate the plan; a fresh planner run on the current volume report usually will not emit a self-referencing step.
- Inspect the plan JSON, remove or fix steps where both sides share a UUID, and recompute the planID (sha1 of the plan bytes) since editing changes the hash.
- If the planner reproducibly emits same-volume steps for this node, attach the node volume report and file a Hadoop JIRA.
Example fix
// before: submit plan that contains a same-volume step
diskBalancer.submitPlan(planID, version, planString, false);
// after: filter degenerate steps client-side before submitting
NodePlan plan = NodePlan.parseJson(planString);
plan.setVolumeSetPlans(plan.getVolumeSetPlans().stream()
.filter(s -> !s.getSourceVolume().getUuid()
.equals(s.getDestinationVolume().getUuid()))
.collect(Collectors.toList()));
String filtered = plan.toJson();
String newPlanId = DigestUtils.sha1Hex(filtered.getBytes(StandardCharsets.UTF_8));
diskBalancer.submitPlan(newPlanId, version, filtered, false); Defensive patterns
Strategy: validation
Validate before calling
for (Step s : NodePlan.parseJson(planString).getVolumeSetPlans()) {
if (s.getSourceVolume().getUuid().equals(s.getDestinationVolume().getUuid())) {
// degenerate step: reject or filter the plan before submitting
}
} Try / catch
try {
diskBalancer.submitPlan(planID, version, plan, false);
} catch (DiskBalancerException e) {
if (e.getResult() == DiskBalancerException.Result.INVALID_MOVE) {
// plan contains a self-move: filter the step, recompute planID hash, resubmit
}
} Prevention
- Sanity-check generated plans for same-volume steps before execution
- Remember any plan edit invalidates the planID — recompute sha1Hex after changes
- Regenerate rather than patch plans when the planner output looks degenerate
When it happens
Trigger: A NodePlan step whose sourceVolumeUUID and destinationVolumeUUID are identical: emitted by the planner when one volume is somehow selected as both most- and least-used, or written manually into the plan JSON.
Common situations: Single-volume or perfectly balanced nodes producing degenerate planner output; hand-edited plans where a volume UUID was pasted into both sides; planner edge cases on tiny or unusual volume sets.
Related errors
- MALFORMED_PLAN
- DATANODE_ID_MISMATCH
- Not a valid Boolean value for {property}
- INVALID_PLAN
- OLD_PLAN_SUBMITTED
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/2134a06f5bb0dfdc.
Report an issue: GitHub.