{"record":{"id":"be5dd53f32339fa4","repo":"apache/hadoop","slug":"datanode-denied-communication-with-namenode-becaus-be5dd5","errorCode":null,"errorMessage":"Datanode denied communication with namenode because the host is not in the include-list: {nodeinfo}","messagePattern":"Datanode denied communication with namenode because the host is not in the include-list: (.+?)","errorType":"exception","errorClass":"DisallowedDatanodeException","httpStatus":null,"severity":"error","filePath":"hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java","lineNumber":1873,"sourceCode":"  /** Handle heartbeat from datanodes. */\n  public DatanodeCommand[] handleHeartbeat(DatanodeRegistration nodeReg,\n      StorageReport[] reports, final String blockPoolId,\n      long cacheCapacity, long cacheUsed, int xceiverCount,\n      int xmitsInProgress, int failedVolumes,\n      VolumeFailureSummary volumeFailureSummary,\n      @Nonnull SlowPeerReports slowPeers,\n      @Nonnull SlowDiskReports slowDisks) throws IOException {\n    final DatanodeDescriptor nodeinfo;\n    try {\n      nodeinfo = getDatanode(nodeReg);\n    } catch (UnregisteredNodeException e) {\n      return new DatanodeCommand[]{RegisterCommand.REGISTER};\n    }\n\n    // Check if this datanode should actually be shutdown instead.\n    if (nodeinfo != null && nodeinfo.isDisallowed()) {\n      setDatanodeDead(nodeinfo);\n      throw new DisallowedDatanodeException(nodeinfo);\n    }\n\n    if (nodeinfo == null || !nodeinfo.isRegistered()) {\n      return new DatanodeCommand[]{RegisterCommand.REGISTER};\n    }\n    heartbeatManager.updateHeartbeat(nodeinfo, reports, cacheCapacity,\n        cacheUsed, xceiverCount, failedVolumes, volumeFailureSummary);\n\n    // If we are in safemode, do not send back any recovery / replication\n    // requests. Don't even drain the existing queue of work.\n    if (namesystem.isInSafeMode()) {\n      return new DatanodeCommand[0];\n    }\n\n    // block recovery command\n    final BlockRecoveryCommand brCommand = getBlockRecoveryCommand(blockPoolId,\n        nodeinfo);\n    if (brCommand != null) {","sourceCodeStart":1855,"sourceCodeEnd":1891,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeManager.java#L1855-L1891","documentation":"Thrown as DisallowedDatanodeException when a DataNode heartbeats to the NameNode while its DatanodeDescriptor is marked disallowed; DatanodeManager first calls setDatanodeDead(nodeinfo) and then rejects the node (DatanodeManager.java:1871-1874). A node becomes disallowed by failing the include-list check that also guards registration (DatanodeManager.java:1213-1215, hostConfigManager.isIncluded), and the exception's default message is exactly 'the host is not in the include-list' (DisallowedDatanodeException.java:46). In effect the NameNode administratively bars the DataNode from the cluster.","triggerScenarios":"A DataNode sends a heartbeat or registration RPC and its host/IP entry is absent from the file configured via dfs.hosts (or is filtered out via dfs.hosts.exclude), typically right after the include file was edited or 'hdfs dfsadmin -refreshNodes' ran. Also triggered when the DN registers with an address (FQDN vs short name, NAT/multi-homed IP) that does not string-match an include-file entry.","commonSituations":"Operators add or remove nodes and forget -refreshNodes; include file lists short hostnames while the DN registers with its FQDN (or vice versa); a new DataNode is installed while dfs.hosts is set but not updated; reverse-DNS of the DN's RPC source address resolves differently from the include entry.","solutions":["Add the DataNode's address exactly as the NameNode reports it in the {nodeinfo} log line (host and IP) to the dfs.hosts include file","Run 'hdfs dfsadmin -refreshNodes' so the NameNode reloads the include/exclude files","Verify forward and reverse DNS for the DataNode matches the include entries (or list both FQDN and IP in dfs.hosts)","Restart the DataNode process if it has backed off and stopped retrying registration","If exclusion was intentional, treat this as expected: complete the decommission and retire or fix the node, then remove it from the lists"],"exampleFix":"# before: dfs.hosts contains only\ndatanode101\n# DN registers as datanode101.example.com -> denied\n\n# after\ndatanode101\ndatanode101.example.com\n# then: hdfs dfsadmin -refreshNodes","handlingStrategy":"try-catch","validationCode":"// preflight before starting/re-registering a DataNode\nString inc = conf.get(\"dfs.hosts\");\nString dnAddr = dnReg.getIpAddr() != null ? dnReg.getIpAddr() : dnReg.getHostName();\nif (inc != null) {\n  List<String> allowed = Files.readAllLines(Paths.get(inc));\n  if (allowed.stream().noneMatch(l -> l.trim().equals(dnAddr))) {\n    throw new IllegalStateException(\"DN \" + dnAddr + \" not in dfs.hosts; add it and run -refreshNodes\");\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  dns.register(namenode, dnRegistration);\n} catch (DisallowedDatanodeException e) {\n  // administrative denial: do NOT retry in a tight loop\n  LOG.error(\"Node disallowed by include-list; fix dfs.hosts and run hdfs dfsadmin -refreshNodes\", e);\n  scheduleReRegisterWithBackoff(); // or halt for operator action\n}","preventionTips":["Keep dfs.hosts entries as exact FQDNs (add IPs alongside) matching what the NameNode logs in the nodeinfo line","Always run 'hdfs dfsadmin -refreshNodes' after every include/exclude edit","Ensure consistent forward/reverse DNS for DataNodes before adding them","Monitor the NameNode log for 'DisallowedDatanode' and alert on first occurrence"],"tags":["hdfs","datanode","namenode","allowlist","dfs-hosts","refresh-nodes"],"backgroundTag":"host-not-in-allowlist","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}