{"record":{"id":"3d9ee32de9fb30cf","repo":"apache/hadoop","slug":"node-is-not-an-ancestor-of-n","errorCode":null,"errorMessage":"${node}is not an ancestor of ${n}","messagePattern":"(.+?)is not an ancestor of (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/InnerNodeImpl.java","lineNumber":115,"sourceCode":"  public boolean isAncestor(Node n) {\n    return getPath(this).equals(NodeBase.PATH_SEPARATOR_STR) ||\n      (n.getNetworkLocation()+NodeBase.PATH_SEPARATOR_STR).\n      startsWith(getPath(this)+NodeBase.PATH_SEPARATOR_STR);\n  }\n\n  /** Judge if this node is the parent of node <i>n</i>.\n   *\n   * @param n a node\n   * @return true if this node is the parent of <i>n</i>\n   */\n  public boolean isParent(Node n) {\n    return n.getNetworkLocation().equals(getPath(this));\n  }\n\n  /* Return a child name of this node who is an ancestor of node <i>n</i> */\n  public String getNextAncestorName(Node n) {\n    if (!isAncestor(n)) {\n      throw new IllegalArgumentException(\n                                         this + \"is not an ancestor of \" + n);\n    }\n    String name = n.getNetworkLocation().substring(getPath(this).length());\n    if (name.charAt(0) == PATH_SEPARATOR) {\n      name = name.substring(1);\n    }\n    int index=name.indexOf(PATH_SEPARATOR);\n    if (index != -1) {\n      name = name.substring(0, index);\n    }\n    return name;\n  }\n\n  @Override\n  public boolean add(Node n) {\n    if (!isAncestor(n)) {\n      throw new IllegalArgumentException(n.getName()\n          + \", which is located at \" + n.getNetworkLocation()","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/InnerNodeImpl.java#L97-L133","documentation":"IllegalArgumentException from InnerNodeImpl.getNextAncestorName(Node) when the node passed in is not a descendant of this inner node — i.e., n.getNetworkLocation() does not start with this node's path in the network topology tree. The method walks one level down from this node toward n, so it first asserts isAncestor(n); the message (note the missing space in the source: '<node>is not an ancestor of <n>') prints both nodes with their locations.","triggerScenarios":"Calling getNextAncestorName(n) where this node's path is '/default-rack' but n's network location is '/dc1/rack2'; a topology script returning inconsistent locations for the same node across calls; node locations missing the leading '/' so prefix comparison fails.","commonSituations":"Misconfigured or nondeterministic topology scripts (dfs.network.script / net.topology.script.file.name); nodes registered under different racks than the ones being searched; malformed network location strings from custom Node implementations.","solutions":["Call isAncestor(n) (or NetworkTopology.isAncestor) before getNextAncestorName and handle the false case","Make the topology script deterministic and normalize locations to the '/a/b' form with a leading '/' and no trailing slash","Log node.getNetworkLocation() for both nodes at the failure point to find which registration produced the divergent path"],"exampleFix":"// before\nInnerNode inner = (InnerNode) node;\nString child = inner.getNextAncestorName(n); // throws if n not under inner\n\n// after\nif (inner.isAncestor(n)) {\n  String child = inner.getNextAncestorName(n);\n} else {\n  LOG.warn(\"{} not under {}; locations: {} vs {}\", n.getName(), inner,\n      n.getNetworkLocation(), inner.getNetworkLocation());\n}","handlingStrategy":"validation","validationCode":"if (!inner.isAncestor(n)) {\n  throw new IllegalStateException(\"location mismatch: \" + n.getNetworkLocation()\n      + \" not under \" + inner.getNetworkLocation());\n}","typeGuard":null,"tryCatchPattern":"catch (IllegalArgumentException e) { /* '<node>is not an ancestor of <n>' */ log both network locations and re-register n under the correct parent; }","preventionTips":["Always test isAncestor(n) before getNextAncestorName(n)","Keep topology script output normalized: leading '/', no trailing '/', fixed depth","Make topology resolution deterministic (same answer for the same node)"],"tags":["network-topology","rack","inner-node","hadoop-common","validation"],"backgroundTag":"invalid-network-location","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}