{"record":{"id":"656793a76ee0355e","repo":"apache/hadoop","slug":"unexpected-data-node-at-an-illegal-network-loca-656793","errorCode":null,"errorMessage":"Unexpected data node {} at an illegal network location","messagePattern":"Unexpected data node (.+?) at an illegal network location","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetworkTopologyWithNodeGroup.java","lineNumber":205,"sourceCode":"      // if node only with default rack info, here we need to add default \n      // nodegroup info\n      if (NetworkTopology.DEFAULT_RACK.equals(node.getNetworkLocation())) {\n        node.setNetworkLocation(node.getNetworkLocation() + \n            NetworkTopologyWithNodeGroup.DEFAULT_NODEGROUP);\n      }\n      Node nodeGroup = getNode(node.getNetworkLocation());\n      if (nodeGroup == null) {\n        nodeGroup = new InnerNodeWithNodeGroup(node.getNetworkLocation());\n      }\n      rack = getNode(nodeGroup.getNetworkLocation());\n\n      // rack should be an innerNode and with parent.\n      // note: rack's null parent case is: node's topology only has one layer, \n      //       so rack is recognized as \"/\" and no parent. \n      // This will be recognized as a node with fault topology.\n      if (rack != null && \n          (!(rack instanceof InnerNode) || rack.getParent() == null)) {\n        throw new IllegalArgumentException(\"Unexpected data node \" \n            + node.toString() \n            + \" at an illegal network location\");\n      }\n      if (clusterMap.add(node)) {\n        LOG.info(\"Adding a new node: \" + NodeBase.getPath(node));\n        if (rack == null) {\n          // We only track rack number here\n          incrementRacks();\n        }\n      }\n      if(LOG.isDebugEnabled()) {\n        LOG.debug(\"NetworkTopology became:\\n\" + this.toString());\n      }\n    } finally {\n      netlock.writeLock().unlock();\n    }\n  }\n","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetworkTopologyWithNodeGroup.java#L187-L223","documentation":"In the node-group topology, add() resolves the new node's rack: it looks up (or creates) the InnerNodeWithNodeGroup at the node's location, then fetches that nodegroup's parent as the rack. The rack must be an InnerNode AND have a parent. A rack that is '/' (null parent) means the node's topology has only one layer, which the code explicitly labels a fault topology and rejects.","triggerScenarios":"A node whose network location has a single component (e.g. '/ng1' or '/default-nodegroup'): the nodegroup's own location resolves to '/', so rack = the root clusterMap whose getParent() is null, and the IllegalArgumentException fires. The other branch fires when the rack path is occupied by a leaf.","commonSituations":"Topology scripts not updated for node-group awareness that return '/rack' or '/nodegroup' instead of '/rack/nodegroup'. Note '/default-rack' is safe: add() auto-appends DEFAULT_NODEGROUP to get '/default-rack/default-nodegroup'; any other single-level location is not.","solutions":["Map every host to a two-component location '/rack/nodegroup'","Return '/default-rack' for unmapped hosts so the class appends the default nodegroup itself","Verify the resulting tree (toString()/dfsadmin -printTopology): every leaf must sit at /rack/nodegroup/host"],"exampleFix":"# before (script output, one layer)\nhost1 -> /ng1\n\n# after (two components)\nhost1 -> /rack1/ng1","handlingStrategy":"validation","validationCode":"String loc = NodeBase.normalize(node.getNetworkLocation());\nint components = loc.equals(\"/\") ? 0 : loc.substring(1).split(\"/\").length;\nif (components != 2) {\n  throw new IllegalArgumentException(\n      \"Node-group topology needs /rack/nodegroup, got: \" + loc);\n}\ntopologyWithNodeGroup.add(node);","typeGuard":"static boolean isNodeGroupLocation(String loc) {\n  if (loc == null || loc.isEmpty() || loc.charAt(0) != '/') return false;\n  return loc.substring(1).split(\"/\").length == 2;\n}","tryCatchPattern":"catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"illegal network location\")) {\n    // rewrite the node location to /rack/nodegroup and retry registration\n  }\n}","preventionTips":["Emit two-component locations from node-group-aware topology scripts","Use '/default-rack' for unmapped hosts so the default nodegroup is appended automatically","Assert the location shape before registration in ingest code"],"tags":["hadoop-common","network-topology","nodegroup","invalid-topology"],"backgroundTag":"network-topology-depth-mismatch","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}