MyCATApache/Mycat-Server · error · SQLNonTransientException
Can't find valid data node(s) for some of specified node…
Error message
Can't find valid data node(s) for some of specified node indexes : + tableConfig.getName() + -> + tableConfig.getPartitionColumn()
What it means
Thrown by RouterUtil when a route calculation resolves node indexes for a sharded table, but one or more indexes are outside the bounds of the table's configured dataNodes list. MyCat refuses to route to a nonexistent node and fails the SQL with SQLNonTransientException. It almost always means the partition rule produces indexes that don't match the table's dataNode configuration.
Solutions
- Align the partition algorithm's count with the number of dataNodes declared for the table in schema.xml (e.g. mod partition count == number of dataNode entries).
- Check schema.xml: every table using the rule must list at least as many dataNodes as the function can return.
- Log the computed partition value and index for the failing row to identify which values map out of range.
- If nodes were intentionally scaled down, re-shard data or switch to a partition function whose range covers the actual node count.
Example fix
// before (rule.xml) <function name="mod-long" class="io.mycat.route.function.PartitionByMod"><property name="count">10</property></function> <!-- but table only has 4 dataNodes --> // after <function name="mod-long" class="io.mycat.route.function.PartitionByMod"><property name="count">4</property></function>
Defensive patterns
Strategy: validation
Validate before calling
// Validate partition index against configured node count before issuing SQL
int idx = partition(value);
List<String> dataNodes = tableConfig.getDataNodes();
if (idx < 0 || idx >= dataNodes.size()) {
throw new IllegalArgumentException("partition index " + idx + " out of range for " + tableConfig.getName() + " (" + dataNodes.size() + " nodes)");
} Prevention
- Keep partition function count equal to dataNode count for every sharded table
- Run MyCat's partition function unit test (e.g. PartitionByModTest) after config changes
- Review schema.xml and rule.xml together in code review
When it happens
Trigger: Executing a SELECT/INSERT/UPDATE routed through ruleResult/RouterUtil.routeToMultiNode (or routeByER/routeToSomeNode) where the partition algorithm returns a node index idx that is <0 or >= dataNodes.size() for tableConfig.getName().
Common situations: Shard count in rule.xml/partition algorithm (e.g. partitionByMod count) larger than the number of <dataNode> entries configured for the table; rule config changed after data nodes were reduced; hash/mod value produces an out-of-range bucket; copy-pasted table config with mismatched node counts.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- only one rule can defined
- can't find function of name
- table rule coulmns has multi values
- rule function duplicated!
- nameSuffix , require name parameter cannot multiple breaks!
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/0cbefbaee60ad220.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/util/RouterUtil.java:1721
}
if(algorithm instanceof SlotFunction){
rrs.getDataNodeSlotMap().put(node,((SlotFunction) algorithm).slotValue());
}
tablesRouteMap.get(tableName).add(node);
}
}
if(pair.rangeValue != null) {
Integer[] nodeIndexs = algorithm
.calculateRange(pair.rangeValue.beginValue.toString(), pair.rangeValue.endValue.toString());
ArrayList<String> dataNodes = tableConfig.getDataNodes();
String node;
for(Integer idx : nodeIndexs) {
if (idx >= 0 && idx < dataNodes.size()) {
node = dataNodes.get(idx);
} else {
String msg = "Can't find valid data node(s) for some of specified node indexes :"
+ tableConfig.getName() + " -> " + tableConfig.getPartitionColumn();
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
if(node != null) {
if(tablesRouteMap.get(tableName) == null) {
tablesRouteMap.put(tableName, new HashSet<String>());
}
if(algorithm instanceof SlotFunction){
rrs.getDataNodeSlotMap().put(node,((SlotFunction) algorithm).slotValue());
}
tablesRouteMap.get(tableName).add(node);
}
}
}
}
}
} else if(joinKey != null && columnsMap.get(joinKey) != null && columnsMap.get(joinKey).size() != 0) {//childTable (如果是select 语句的父子表join)之前要找到root table,将childTable移除,只留下root table
Set<ColumnRoutePair> joinKeyValue = columnsMap.get(joinKey);
View on GitHub (pinned to 65f8d8beb7)