{"record":{"id":"1980f25b463ad422","repo":"MyCATApache/Mycat-Server","slug":"can-t-find-any-valid-datanode","errorCode":null,"errorMessage":"can't find any valid datanode : ->  -> ","messagePattern":"can't find any valid datanode : ->  -> ","errorType":"exception","errorClass":"SQLNonTransientException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/parser/druid/impl/DruidInsertParser.java","lineNumber":268,"sourceCode":"\t\t\t\t\t             + columnNum + \" != \" + valueClause.getValues().size() \n\t\t\t\t\t             + \"values:\" + valueClause;\n\t\t\t\t\t\tLOGGER.warn(msg);\n\t\t\t\t\t\tthrow new SQLNonTransientException(msg);\n\t\t\t\t\t}\n\t\t\t\t\tSQLExpr expr = valueClause.getValues().get(shardingColIndex);\n\t\t\t\t\tString shardingValue = StringUtil.removeBackquote(getShardingValue(expr));\n\t\t\t\t\tvalueClause.getValues().set(shardingColIndex, new SQLCharExpr(shardingValue));\n\n\t\t\t\t\tInteger nodeIndex = algorithm.calculate(StringUtil.removeBackquote(shardingValue));\n\t\t\t\t\tif(algorithm instanceof SlotFunction){\n\t\t\t\t\t\tslotsMap.put(nodeIndex,((SlotFunction) algorithm).slotValue()) ;\n\t\t\t\t\t}\n\t\t\t\t\t//没找到插入的分片\n\t\t\t\t\tif(nodeIndex == null) {\n\t\t\t\t\t\tString msg = \"can't find any valid datanode :\" + tableName \n\t\t\t\t\t\t\t\t+ \" -> \" + partitionColumn + \" -> \" + shardingValue;\n\t\t\t\t\t\tLOGGER.warn(msg);\n\t\t\t\t\t\tthrow new SQLNonTransientException(msg);\n\t\t\t\t\t}\n\t\t\t\t\tif(nodeValuesMap.get(nodeIndex) == null) {\n\t\t\t\t\t\tnodeValuesMap.put(nodeIndex, new ArrayList<ValuesClause>());\n\t\t\t\t\t}\n\t\t\t\t\tnodeValuesMap.get(nodeIndex).add(valueClause);\n\t\t\t\t}\n\n\n\t\t\t\tRouteResultsetNode[] nodes = new RouteResultsetNode[nodeValuesMap.size()];\n\t\t\t\tint count = 0;\n\t\t\t\tfor(Map.Entry<Integer,List<ValuesClause>> node : nodeValuesMap.entrySet()) {\n\t\t\t\t\tInteger nodeIndex = node.getKey();\n\t\t\t\t\tList<ValuesClause> valuesList = node.getValue();\n\t\t\t\t\tinsertStmt.getValuesList().clear();\n\t\t\t\t\tinsertStmt.getValuesList().addAll(valuesList);\n\t\t\t\t\t// insertStmt.setValuesList(valuesList);\n\t\t\t\t\tif(tableConfig.isDistTable()) {\n\t\t\t\t\t\tnodes[count] = new RouteResultsetNode(tableConfig.getDataNodes().get(0),","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/parser/druid/impl/DruidInsertParser.java#L250-L286","documentation":"In parserBatchInsert, after computing the sharding value for each VALUES clause, the sharding algorithm (algorithm.calculate) returned null, meaning no datanode matches that sharding value. MyCat cannot route the row and throws SQLNonTransientException naming the table, partition column, and the unresolvable sharding value.","triggerScenarios":"statementParse -> parserBatchInsert on a sharded INSERT where the value of the partition/sharding column falls outside the ranges or enum values configured in the sharding rule (rule.xml function), so calculate() returns null.","commonSituations":"Sharding hash/range function configured for values 0-100 but insert uses id=500; partition column value is null, empty, or non-numeric; rule changed after data was written; autocreator generated a node count that the algorithm can't map to.","solutions":["Check the sharding value in the message against the sharding function configuration in rule.xml and widen the rule's range/count to cover it","Correct the application data so the partition column value is inside the configured range","Verify sharding column name casing/backquotes matches the table config's partitionColumn","If the value can be out of range by design, use a sharding algorithm with a default node"],"exampleFix":"// before (rule.xml range covers 0-100)\nINSERT INTO t(id) VALUES (500);\n// after (extend rule defaultNode or fix data)\nINSERT INTO t(id) VALUES (50);","handlingStrategy":"validation","validationCode":"Object v = shardingValueOf(row); if (v == null || !shardingRuleCovers(v)) throw new IllegalArgumentException(\"sharding value not covered: \" + v);","typeGuard":"boolean isRoutableShardValue(Integer nodeIndex) { return nodeIndex != null; }","tryCatchPattern":"try { route(sql); } catch (SQLNonTransientException e) { if (e.getMessage().startsWith(\"can't find any valid datanode\")) { handleUnshardableRow(e); } else throw e; }","preventionTips":["Keep the sharding algorithm's value range in sync with application IDs","Never write NULL into a partition column","After changing rule.xml, test boundary sharding values","Add a defaultNode to sharding functions for out-of-range values"],"tags":["sql","sharding","routing","datanode"],"backgroundTag":"resource-not-found","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"}