apache/hadoop · error · IllegalArgumentException
${node}is not an ancestor of ${n}
Error message
${node}is not an ancestor of ${n} What it means
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.
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/InnerNodeImpl.java:115
public boolean isAncestor(Node n) {
return getPath(this).equals(NodeBase.PATH_SEPARATOR_STR) ||
(n.getNetworkLocation()+NodeBase.PATH_SEPARATOR_STR).
startsWith(getPath(this)+NodeBase.PATH_SEPARATOR_STR);
}
/** Judge if this node is the parent of node <i>n</i>.
*
* @param n a node
* @return true if this node is the parent of <i>n</i>
*/
public boolean isParent(Node n) {
return n.getNetworkLocation().equals(getPath(this));
}
/* Return a child name of this node who is an ancestor of node <i>n</i> */
public String getNextAncestorName(Node n) {
if (!isAncestor(n)) {
throw new IllegalArgumentException(
this + "is not an ancestor of " + n);
}
String name = n.getNetworkLocation().substring(getPath(this).length());
if (name.charAt(0) == PATH_SEPARATOR) {
name = name.substring(1);
}
int index=name.indexOf(PATH_SEPARATOR);
if (index != -1) {
name = name.substring(0, index);
}
return name;
}
@Override
public boolean add(Node n) {
if (!isAncestor(n)) {
throw new IllegalArgumentException(n.getName()
+ ", which is located at " + n.getNetworkLocation()View on GitHub (pinned to 2add963021)
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
Example fix
// before
InnerNode inner = (InnerNode) node;
String child = inner.getNextAncestorName(n); // throws if n not under inner
// after
if (inner.isAncestor(n)) {
String child = inner.getNextAncestorName(n);
} else {
LOG.warn("{} not under {}; locations: {} vs {}", n.getName(), inner,
n.getNetworkLocation(), inner.getNetworkLocation());
} Defensive patterns
Strategy: validation
Validate before calling
if (!inner.isAncestor(n)) {
throw new IllegalStateException("location mismatch: " + n.getNetworkLocation()
+ " not under " + inner.getNetworkLocation());
} Try / catch
catch (IllegalArgumentException e) { /* '<node>is not an ancestor of <n>' */ log both network locations and re-register n under the correct parent; } Prevention
- 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)
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ${name}, which is located at ${networkLocation}, is not a de
- Wrong length: {digest.length}
- Wrong length: {hex.length}
- Not a hex character: {c}
- No schema options are provided
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/3d9ee32de9fb30cf.
Report an issue: GitHub.