MyCATApache/Mycat-Server · error · java.sql.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
Variant of the node-index routing failure used when the rule yields indexes for a set of values (e.g. IN clause): at least one computed index falls outside the table's configured dataNode range. Mycat cannot resolve every value to a data node, so the whole statement fails with SQLNonTransientException rather than routing partially.
Solutions
- Compare each IN-list value's computed index against dataNodes.size(); add missing dataNodes to schema.xml or adjust the rule
- Review recent changes to rule.xml/partition files and revert bucket counts to match the dataNode list
- Split the query so values mapping to valid nodes are routed, and investigate out-of-range values separately
- Ensure the partition algorithm cannot emit negative indexes (hash functions returning int can go negative)
Example fix
// before SELECT * FROM t_order WHERE user_id IN (1, 999999999); -- 999999999 -> idx out of range // after: shrink domain or add nodes <table name="t_order" dataNode="dn1,dn2,...,dnN" rule="sharding-by-murmur" /> // N >= maxIndex+1
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check every IN-list value before sending the query
for (Object v : inValues) {
int idx = rule.calculate(v);
if (idx < 0 || idx >= nodeCount) throw new IllegalArgumentException("value out of sharding range: " + v);
} Try / catch
catch (SQLNonTransientException e) { if (e.getMessage().contains("valid data node(s)")) { /* split query or fix config */ } else throw e; } Prevention
- Validate ID ranges in the application layer against current shard count
- Never change dataNode count without a data migration plan
- Log table + partition column + values on route failures for fast triage
When it happens
Trigger: A query with IN (...) or multiple values on the partition column; RouterUtil's per-pair index loop finds idx < 0 || idx >= dataNodes.size() for any one value.
Common situations: Bulk queries with historical IDs written when more dataNodes existed; partition function bucket count changed; copy-pasted rule config from another schema with more nodes; typo in dataNode list in schema.xml.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Can't find a valid data node for specified node index
- can't find any valid datanode : -> ->
- can't find any valid datanode
- columnValue: Please eliminate any quote and non number…
- columnValue: Please check if the format satisfied.
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/60b9530c660fb427.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/util/RouterUtil.java:1722
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)