MyCATApache/Mycat-Server · error · SQLNonTransientException
can't find hint datanode
Error message
can't find hint datanode:{hintSQLValue} What it means
HintDataNodeHandler.route() handles the /*+ datanode=name */ Mycat hint by looking up hintSQLValue in MycatServer's configured datanodes. If no datanode with that name exists, it logs a warning and throws SQLNonTransientException. The SQL is not routed anywhere because the hinted target does not exist.
Solutions
- Correct the hint to an existing datanode name exactly as declared in schema.xml (e.g. /*+ mycat:datanode=dn1 */).
- Cross-check the datanode name in Mycat's running config (show @@datanode) and fix the application's hint string.
- If the datanode was removed/renamed, either restore the old name in schema.xml or update all clients that send the hint.
- Add client-side validation of hint names against known datanodes before sending SQL.
Example fix
// before String sql = "/*!mycat: datanode = dataNodeOld*/ SELECT * FROM t"; // SQLNonTransientException // after String sql = "/*!mycat: datanode = dn1*/ SELECT * FROM t"; // dn1 exists in schema.xml
Defensive patterns
Strategy: validation
Validate before calling
Set<String> known = MycatServer.getInstance().getConfig().getDataNodes().keySet();
if (!known.contains(hintDataNode)) throw new IllegalArgumentException("unknown datanode in hint: " + hintDataNode); Try / catch
try { stmt.execute(hintedSql); } catch (SQLNonTransientException e) { if (e.getMessage().startsWith("can't find hint datanode:")) { /* fix hint name against schema.xml datanodes */ } throw e; } Prevention
- Generate hint names from the same source of truth as schema.xml, not hand-written strings.
- Re-check hints after any datanode rename/removal migration.
- Verify hints with show @@datanode on the Mycat management port before rollout.
When it happens
Trigger: Executing SQL with a hint like /*!mycat: datanode = dn1*/ (or the /*+ ... */ form) where dn1 is not defined in schema.xml's <dataNode> entries, including typos, stale names after a config change, or hints targeting datanodes on a different Mycat instance.
Common situations: Typo in the hint comment; renaming datanodes during scaling operations while application code still emits the old hint; environment mismatch where test configs name datanodes differently than production; whitespace/case issues in the hint value.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- can't find hint schema
- can't find any valid datanode : -> ->
- "can't find hint datanode:" + hintSQLValue
- schema: ,table: ,sql: is not allowed,because table is…
- file name is null !
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/ba0f4e3171c1490b.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/handler/HintDataNodeHandler.java:51
@Override
public RouteResultset route(SystemConfig sysConfig, SchemaConfig schema, int sqlType, String realSQL,
String charset, ServerConnection sc, LayerCachePool cachePool, String hintSQLValue,int hintSqlType, Map hintMap)
throws SQLNonTransientException {
String stmt = realSQL;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("route datanode sql hint from " + stmt);
}
RouteResultset rrs = new RouteResultset(stmt, sqlType);
PhysicalDBNode dataNode = MycatServer.getInstance().getConfig().getDataNodes().get(hintSQLValue);
if (dataNode != null) {
rrs = RouterUtil.routeToSingleNode(rrs, dataNode.getName(), stmt);
} else {
String msg = "can't find hint datanode:" + hintSQLValue;
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
// 处理导入参数初始化
if(rrs.getSqlType() == ServerParse.LOAD_DATA_INFILE_SQL){
LOGGER.info("load data use annotation datanode");
rrs.getNodes()[0].setLoadData(parseLoadDataPram(stmt , charset));
}
return rrs;
}
// 初始化导入参数
private LoadData parseLoadDataPram(String sql , String connectionCharset)
{
SQLStatementParser parser = new MycatStatementParser(sql);
MySqlLoadDataInFileStatement statement = (MySqlLoadDataInFileStatement) parser.parseStatement();
LoadData loadData = new LoadData();View on GitHub (pinned to 65f8d8beb7)