{"record":{"id":"53ab072e7bc6ba65","repo":"MyCATApache/Mycat-Server","slug":"can-t-find-a-valid-data-node-for-specified-node-in-53ab07","errorCode":null,"errorMessage":"Can't find a valid data node for specified node index : + tableConfig.getName() +  ->  + tableConfig.getPartitionColumn() +  ->  + pair.colValue +  ->  + Index :  + nodeIndex","messagePattern":"Can't find a valid data node for specified node index : \\+ tableConfig\\.getName\\(\\) \\+  ->  \\+ tableConfig\\.getPartitionColumn\\(\\) \\+  ->  \\+ pair\\.colValue \\+  ->  \\+ Index :  \\+ nodeIndex","errorType":"exception","errorClass":"SQLNonTransientException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/util/RouterUtil.java","lineNumber":1697,"sourceCode":"\t\t\t\t\t\t\t\tInteger nodeIndex = algorithm.calculate(StringUtil.removeBackquote(pair.colValue));\r\n\t\t\t\t\t\t\t\tif(nodeIndex == null) {\r\n\t\t\t\t\t\t\t\t\tString msg = \"can't find any valid datanode :\" + tableConfig.getName()\r\n\t\t\t\t\t\t\t\t\t\t\t+ \" -> \" + tableConfig.getPartitionColumn() + \" -> \" + pair.colValue;\r\n\t\t\t\t\t\t\t\t\tLOGGER.warn(msg);\r\n\t\t\t\t\t\t\t\t\tthrow new SQLNonTransientException(msg);\r\n\t\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t\tArrayList<String> dataNodes = tableConfig.getDataNodes();\r\n\t\t\t\t\t\t\t\tString node;\r\n\t\t\t\t\t\t\t\tif (nodeIndex >=0 && nodeIndex < dataNodes.size()) {\r\n\t\t\t\t\t\t\t\t\tnode = dataNodes.get(nodeIndex);\r\n\r\n\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\tnode = null;\r\n\t\t\t\t\t\t\t\t\tString msg = \"Can't find a valid data node for specified node index :\"\r\n\t\t\t\t\t\t\t\t\t\t\t+ tableConfig.getName() + \" -> \" + tableConfig.getPartitionColumn()\r\n\t\t\t\t\t\t\t\t\t\t\t+ \" -> \" + pair.colValue + \" -> \" + \"Index : \" + nodeIndex;\r\n\t\t\t\t\t\t\t\t\tLOGGER.warn(msg);\r\n\t\t\t\t\t\t\t\t\tthrow new SQLNonTransientException(msg);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tif(node != null) {\r\n\t\t\t\t\t\t\t\t\tif(tablesRouteMap.get(tableName) == null) {\r\n\t\t\t\t\t\t\t\t\t\ttablesRouteMap.put(tableName, new HashSet<String>());\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tif(algorithm instanceof SlotFunction){\r\n\t\t\t\t\t\t\t\t\t\trrs.getDataNodeSlotMap().put(node,((SlotFunction) algorithm).slotValue());\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\ttablesRouteMap.get(tableName).add(node);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif(pair.rangeValue != null) {\r\n\t\t\t\t\t\t\t\tInteger[] nodeIndexs = algorithm\r\n\t\t\t\t\t\t\t\t\t\t.calculateRange(pair.rangeValue.beginValue.toString(), pair.rangeValue.endValue.toString());\r\n\t\t\t\t\t\t\t\tArrayList<String> dataNodes = tableConfig.getDataNodes();\r\n\t\t\t\t\t\t\t\tString node;\r\n\t\t\t\t\t\t\t\tfor(Integer idx : nodeIndexs) {\r","sourceCodeStart":1679,"sourceCodeEnd":1715,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/util/RouterUtil.java#L1679-L1715","documentation":"After the algorithm computes a node index for a partition-column value, RouterUtil validates nodeIndex against the table's dataNodes list (0 <= index < size). An out-of-bounds index means the sharding function returned an index with no configured data node, and it throws SQLNonTransientException including the index value.","triggerScenarios":"algorithm.calculate() returns an index >= dataNodes.size() (or negative) — e.g. a hash/mod rule configured with count larger than the number of dataNodes on the table.","commonSituations":"Rule function count increased or table dataNodes reduced without keeping them in sync; custom algorithm returning 1-based indexes or bad values; schema.xml edited to remove nodes while rule.xml still maps to them.","solutions":["Align rule.xml function count/ranges with the table's dataNode count in schema.xml (e.g. count equals number of dataNodes) and reload both","Fix the custom partition algorithm so returned indexes are 0-based and within [0, nodeCount)","Add the missing dataNode(s) referenced by the rule to the table config"],"exampleFix":"// before (rule.xml) count=10 but only 4 dataNodes\n<property name=\"count\">10</property>\n// after\n<property name=\"count\">4</property>","handlingStrategy":"validation","validationCode":"// check rule count matches dataNode count before deploy\nint count = ruleFunctionCount(\"mod-rule\");      // from rule.xml\nint nodes = tableDataNodeCount(\"orders\");      // from schema.xml\nif (count != nodes) throw new IllegalStateException(\"Rule count \" + count + \" != dataNode count \" + nodes);","typeGuard":null,"tryCatchPattern":"try {\n    execute(query);\n} catch (SQLNonTransientException e) {\n    if (e.getMessage().contains(\"for specified node index\"))\n        throw new IllegalStateException(\"rule.xml count out of sync with schema.xml dataNodes\", e);\n    throw e;\n}","preventionTips":["Keep rule function count exactly equal to the table's dataNode count","CI-lint rule.xml against schema.xml on every config change","Ensure custom AbstractPartitionAlgorithm implementations return 0-based indexes within range"],"tags":["sql","routing","sharding","config-mismatch"],"backgroundTag":"value-out-of-range","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}