{"record":{"id":"8fe08addc1e53486","repo":"apache/hadoop","slug":"not-allow-to-add-an-inner-node","errorCode":null,"errorMessage":"Not allow to add an inner node: {}","messagePattern":"Not allow to add an inner node: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetworkTopology.java","lineNumber":139,"sourceCode":"  // keeping the constructor because other components like MR still uses this.\n  public NetworkTopology() {\n    this.factory = InnerNodeImpl.FACTORY;\n    this.clusterMap = factory.newInnerNode(NodeBase.ROOT);\n  }\n\n  /** 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) {","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/NetworkTopology.java#L121-L157","documentation":"NetworkTopology.add(Node) registers only leaf nodes (datanodes). InnerNode objects are the internal structural entities (racks/switches) that the topology creates and manages itself while inserting a leaf, so passing one is a usage error and throws IllegalArgumentException before the write lock is even taken.","triggerScenarios":"Calling clusterMap.add(node) where node instanceof InnerNode (InnerNodeImpl, InnerNodeWithNodeGroup, or any subclass). Typical: constructing an InnerNode directly and adding it, or re-adding a node previously fetched via getNode()/getDatanodesInRack(), which can return inner nodes.","commonSituations":"Custom Node implementations or test mocks that extend InnerNode; block-placement or replica code that round-trips nodes obtained from NetworkTopology lookups; code ported between NetworkTopology and NetworkTopologyWithNodeGroup where the same guard exists.","solutions":["Pass only leaf nodes (DatanodeDescriptor, NodeBase, or a custom Node that does not extend InnerNode) to add()","If the node came from getNode()/getLeaf()/getDatanodesInRack(), filter with !(node instanceof InnerNode) before calling add()","Never construct InnerNodeImpl yourself; the topology builds rack levels automatically when a leaf is added"],"exampleFix":"// before\ntopology.add(nodeFromLookup); // nodeFromLookup may be an InnerNode\n\n// after\nif (nodeFromLookup instanceof InnerNode) {\n  throw new IllegalArgumentException(\"Only leaf nodes can be added: \"\n      + NodeBase.getPath(nodeFromLookup));\n}\ntopology.add(nodeFromLookup);","handlingStrategy":"validation","validationCode":"if (node instanceof InnerNode) {\n  throw new IllegalArgumentException(\n      \"Refusing to add inner node \" + NodeBase.getPath(node));\n}\ntopology.add(node);","typeGuard":"static boolean isAddableLeaf(Node n) {\n  return n != null && !(n instanceof InnerNode);\n}","tryCatchPattern":null,"preventionTips":["Filter every node that comes from getNode()/getDatanodesInRack() before re-adding it","Keep custom Node implementations extending NodeBase, not InnerNode","Assert the guard in unit tests that exercise add/remove round-trips"],"tags":["hadoop-common","network-topology","invalid-argument","java"],"backgroundTag":"inner-node-rejected","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}