{"record":{"id":"31c7caeb789deb4a","repo":"MyCATApache/Mycat-Server","slug":"can-t-find-any-valid-datanode-tableconfig-getn","errorCode":null,"errorMessage":"can't find any valid datanode : + tableConfig.getName() +  ->  + tableConfig.getPartitionColumn() +  ->  + pair.colValue","messagePattern":"can't find any valid datanode : \\+ tableConfig\\.getName\\(\\) \\+  ->  \\+ tableConfig\\.getPartitionColumn\\(\\) \\+  ->  \\+ pair\\.colValue","errorType":"exception","errorClass":"SQLNonTransientException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/util/RouterUtil.java","lineNumber":1501,"sourceCode":"    }\r\n\t\r\n\tprivate static void setNodes(RouteResultset rrs, TableConfig tableConfig, String partionCol,\r\n        Set<String> tablesRouteSet, Map.Entry<String, Map<String, Set<ColumnRoutePair>>> entry1)\r\n        throws SQLNonTransientException {\r\n        Map<String, Set<ColumnRoutePair>> columnsMap = entry1.getValue();\r\n    \r\n        Set<ColumnRoutePair> partitionValue = columnsMap.get(partionCol);\r\n        if(partitionValue == null || partitionValue.size() == 0) {\r\n            tablesRouteSet.addAll(tableConfig.getDistTables());\r\n        } else {\r\n            for(ColumnRoutePair pair : partitionValue) {\r\n                AbstractPartitionAlgorithm algorithm = tableConfig.getRule().getRuleAlgorithm();\r\n                if(pair.colValue != null) {\r\n                    Integer tableIndex = algorithm.calculate(pair.colValue);\r\n                    if(tableIndex == null) {\r\n                        String msg = \"can't find any valid datanode :\" + tableConfig.getName()\r\n                                + \" -> \" + tableConfig.getPartitionColumn() + \" -> \" + pair.colValue;\r\n                        LOGGER.warn(msg);\r\n                        throw new SQLNonTransientException(msg);\r\n                    }\r\n                    String subTable = tableConfig.getDistTables().get(tableIndex);\r\n                    if(subTable != null) {\r\n                        tablesRouteSet.add(subTable);\r\n                        if(algorithm instanceof SlotFunction){\r\n                            rrs.getDataNodeSlotMap().put(subTable,((SlotFunction) algorithm).slotValue());\r\n                        }\r\n                    }\r\n                }\r\n                if(pair.rangeValue != null) {\r\n                    Integer[] tableIndexs = algorithm\r\n                            .calculateRange(pair.rangeValue.beginValue.toString(), pair.rangeValue.endValue.toString());\r\n                    for(Integer idx : tableIndexs) {\r\n                        String subTable = tableConfig.getDistTables().get(idx);\r\n                        if(subTable != null) {\r\n                            tablesRouteSet.add(subTable);\r\n                            if(algorithm instanceof SlotFunction){\r","sourceCodeStart":1483,"sourceCodeEnd":1519,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/util/RouterUtil.java#L1483-L1519","documentation":"While routing a district (dist) table, RouterUtil feeds each condition value of the partition column into the rule's AbstractPartitionAlgorithm.calculate(). A null return means the sharding algorithm cannot map the value to any table index, so it throws SQLNonTransientException naming table, partition column, and the offending value.","triggerScenarios":"Executing a query/insert on a dist table where a WHERE/JOIN condition value for the partition column falls outside the algorithm's valid domain (e.g. string fed to a numeric hash, value outside enumerated range).","commonSituations":"Partition function (e.g. PartitionByString/mod-long) cannot handle the value type or range; data contains legacy/garbage values not covered by the partition map; column values changed after the rule was configured; NULL-adjacent sentinel values.","solutions":["Fix the data value or add a partition rule branch covering that value's range/type","Adjust the partition algorithm configuration (count/mapFile) to cover the full value domain and reload","Clean or transform invalid partition-column values before they reach MyCat","Add a default route in the rule so unmapped values fall to a designated node"],"exampleFix":"// before\nalgorithm.calculate(\"abc\") -> null // mod-long rule on a varchar column\n// after (rule.xml)\n<function name=\"hash-string\" class=\"io.mycat.route.function.PartitionByString\">\n  <property name=\"count\">3</property>\n</function> // or cast the column value before querying","handlingStrategy":"validation","validationCode":"// pre-check that partition values are mappable (example: mod-long)\nObject v = row.get(partitionColumn);\nif (v == null || !(v instanceof Number))\n    throw new IllegalArgumentException(\"Partition column \" + partitionColumn + \" must be a non-null number for this rule: \" + v);","typeGuard":null,"tryCatchPattern":"try {\n    execute(shardedQuery);\n} catch (SQLNonTransientException e) {\n    if (e.getMessage().startsWith(\"can't find any valid datanode\")) {\n        log.warn(\"Unroutable partition value: \" + e.getMessage());\n        // route to a direct data-node connection or quarantine the value\n    } else throw e;\n}","preventionTips":["Validate partition-column values (type/range) at application boundary before queries","Cover the full value domain in rule.xml (ranges, count, mapFile)","Add tests exercising min/max/typical partition values against the algorithm"],"tags":["sql","routing","sharding","partition-function"],"backgroundTag":"invalid-argument-value","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"}