{"record":{"id":"ef414a4d6968991c","repo":"apache/hadoop","slug":"failed-to-add-you-cannot-have-a-rack-and-a-non","errorCode":null,"errorMessage":"Failed to add {}: You cannot have a rack and a non-rack node at the same level of the network topology.","messagePattern":"Failed to add (.+?): You cannot have a rack and a non-rack node at the same level of the network topology\\.","errorType":"exception","errorClass":"InvalidTopologyException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetworkTopology.java","lineNumber":145,"sourceCode":"  /** Add a leaf node\n   * Update node counter &amp; rack counter if necessary\n   * @param node node to be added; can be null\n   * @exception IllegalArgumentException if add a node to a leave \n                                         or node to be added is not a leaf\n   */\n  public void add(Node node) {\n    if (node==null) return;\n    int newDepth = NodeBase.locationToDepth(node.getNetworkLocation()) + 1;\n    netlock.writeLock().lock();\n    try {\n      if( node instanceof InnerNode ) {\n        throw new IllegalArgumentException(\n          \"Not allow to add an inner node: \"+NodeBase.getPath(node));\n      }\n      if ((depthOfAllLeaves != -1) && (depthOfAllLeaves != newDepth)) {\n        LOG.error(\"Error: can't add leaf node {} at depth {} to topology:{}\\n\",\n            NodeBase.getPath(node), newDepth, this);\n        throw new InvalidTopologyException(\"Failed to add \" + NodeBase.getPath(node) +\n            \": You cannot have a rack and a non-rack node at the same \" +\n            \"level of the network topology.\");\n      }\n      Node rack = getNodeForNetworkLocation(node);\n      if (rack != null && !(rack instanceof InnerNode)) {\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          incrementRacks();\n        }\n        interAddNodeWithEmptyRack(node);\n        if (depthOfAllLeaves == -1) {\n          depthOfAllLeaves = node.getLevel();\n        }","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetworkTopology.java#L127-L163","documentation":"add(Node) enforces a uniform leaf depth: the first inserted leaf records depthOfAllLeaves, and every later leaf whose depth (locationToDepth(location)+1) differs throws InvalidTopologyException. Hadoop's cluster map cannot represent a rack and a non-rack node at the same topology level, so mixed-depth mappings are rejected.","triggerScenarios":"The first node registers at /default-rack (unmapped fallback) and a later node at /dc1/rack1, or vice versa: any add() where the new node's network location has a different number of path components than the existing leaves. LOG.error prints the offending path, its depth, and the current topology just before the throw.","commonSituations":"net.topology.script.file-name returning different-depth outputs per host (script bug, DNS timeout for some hosts silently falling back to /default-rack); hosts missing from StaticMapping key-value data while others get multi-level racks; changing script output shape while the cluster is running.","solutions":["Run `hdfs dfsadmin -printTopology` and identify which node reports a different depth than the rest; fix that host's mapping","Make the topology script or StaticMapping return the same number of path components for every host (all /rack or all /dc/rack)","Fix scripts that fail or time out for some hosts so they never silently emit /default-rack in a multi-level cluster"],"exampleFix":"# before (script output, inconsistent)\nhost1 -> /default-rack\nhost2 -> /dc1/rack1\n\n# after (uniform depth)\nhost1 -> /dc1/rack1\nhost2 -> /dc1/rack2","handlingStrategy":"validation","validationCode":"int newDepth = NodeBase.locationToDepth(node.getNetworkLocation()) + 1;\nfor (Node existing : topology.getLeaves(NodeBase.ROOT)) {\n  if (existing.getLevel() != newDepth) {\n    throw new InvalidTopologyException(\"Depth mismatch for \"\n        + NodeBase.getPath(node));\n  }\n}\ntopology.add(node);","typeGuard":"static boolean isUniformDepth(NetworkTopology t, Node candidate) {\n  int d = NodeBase.locationToDepth(candidate.getNetworkLocation()) + 1;\n  return t.getLeaves(NodeBase.ROOT).stream().allMatch(n -> n.getLevel() == d);\n}","tryCatchPattern":"catch (InvalidTopologyException e) { // config problem, not transient: log and refuse to register the node\n  LOG.error(\"Rejecting node with non-uniform topology depth: {}\", e.getMessage());\n}","preventionTips":["Validate script/StaticMapping output depth for all hosts before deploying new nodes","Monitor dfsadmin -printTopology in CI or cluster smoke tests","Never let the mapping silently fall back to /default-rack in a multi-level cluster"],"tags":["hadoop-common","network-topology","configuration","hdfs","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"}