apache/hadoop · error · UnsupportedOperationException
Received unimplemented DNA_SHUTDOWN
Error message
Received unimplemented DNA_SHUTDOWN
What it means
The DataNode's command dispatcher has a case for DatanodeProtocol.DNA_SHUTDOWN that intentionally throws UnsupportedOperationException — as the code comment notes, the stock NameNode never sends this command (HDFS-2987) and the DN has no handler for it. Receiving it means the peer is not behaving like a stock NN.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/BPOfferService.java:773
throw e;
}
break;
case DatanodeProtocol.DNA_CACHE:
LOG.info("DatanodeCommand action: DNA_CACHE for " +
blockIdCmd.getBlockPoolId() + " of [" +
blockIdArrayToString(blockIdCmd.getBlockIds()) + "]");
dn.getFSDataset().cache(blockIdCmd.getBlockPoolId(), blockIdCmd.getBlockIds());
break;
case DatanodeProtocol.DNA_UNCACHE:
LOG.info("DatanodeCommand action: DNA_UNCACHE for " +
blockIdCmd.getBlockPoolId() + " of [" +
blockIdArrayToString(blockIdCmd.getBlockIds()) + "]");
dn.getFSDataset().uncache(blockIdCmd.getBlockPoolId(), blockIdCmd.getBlockIds());
break;
case DatanodeProtocol.DNA_SHUTDOWN:
// TODO: DNA_SHUTDOWN appears to be unused - the NN never sends this command
// See HDFS-2987.
throw new UnsupportedOperationException("Received unimplemented DNA_SHUTDOWN");
case DatanodeProtocol.DNA_FINALIZE:
String bp = ((FinalizeCommand) cmd).getBlockPoolId();
LOG.info("Got finalize command for block pool " + bp);
assert getBlockPoolId().equals(bp) :
"BP " + getBlockPoolId() + " received DNA_FINALIZE " +
"for other block pool " + bp;
dn.finalizeUpgradeForPool(bp);
break;
case DatanodeProtocol.DNA_RECOVERBLOCK:
String who = "NameNode at " + nnSocketAddress;
dn.getBlockRecoveryWorker().recoverBlocks(who,
((BlockRecoveryCommand)cmd).getRecoveringBlocks());
break;
case DatanodeProtocol.DNA_ACCESSKEYUPDATE:
LOG.info("DatanodeCommand action from active NN {}: DNA_ACCESSKEYUPDATE", nnSocketAddress);
if (dn.isBlockTokenEnabled) {
dn.blockPoolTokenSecretManager.addKeys(View on GitHub (pinned to 2add963021)
Solutions
- Stop sending DNA_SHUTDOWN from custom NN-side code — decommission + stopping the DN process is the supported path
- If this comes from a stock NN, capture the NN version and heartbeat trace and file a HADOOP JIRA; it indicates protocol corruption
Defensive patterns
Strategy: try-catch
Try / catch
// Only relevant for custom command dispatchers built on DatanodeProtocol
try {
processCommands(cmds);
} catch (UnsupportedOperationException e) {
if (e.getMessage() != null && e.getMessage().contains("DNA_SHUTDOWN")) {
// peer is not a stock NN: log and refuse instead of killing the actor thread
LOG.error("Peer sent unimplemented DNA_SHUTDOWN; ignoring command source");
} else {
throw e;
}
} Prevention
- Do not send legacy DNA_SHUTDOWN from custom NN-side code; use decommission and process control
- Keep DN and NN protocol versions aligned in mixed-version rollouts
When it happens
Trigger: A modified/forked NameNode, test harness, or crafted DatanodeProtocol response includes DNA_SHUTDOWN in a heartbeat reply; the DN's actor thread hits the unhandled case and dies.
Common situations: In-house NN forks reusing the ancient shutdown command; protocol fuzzing/replay tests; extremely old pre-2.x protocol semantics reused in tooling.
Related errors
- DN shut down before block pool connected
- DN shut down before block pool registered
- Shutdown already in progress.
- Cannot finalize block: {b} from Interrupted Thread
- The volume has already closed.
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/6bf480925fd197bc.
Report an issue: GitHub.