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

  1. Compare each IN-list value's computed index against dataNodes.size(); add missing dataNodes to schema.xml or adjust the rule
  2. Review recent changes to rule.xml/partition files and revert bucket counts to match the dataNode list
  3. Split the query so values mapping to valid nodes are routed, and investigate out-of-range values separately
  4. 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

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


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)