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

  1. 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).
  2. Check schema.xml: every table using the rule must list at least as many dataNodes as the function can return.
  3. Log the computed partition value and index for the failing row to identify which values map out of range.
  4. 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

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


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)