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

  1. Correct the hint to an existing datanode name exactly as declared in schema.xml (e.g. /*+ mycat:datanode=dn1 */).
  2. Cross-check the datanode name in Mycat's running config (show @@datanode) and fix the application's hint string.
  3. If the datanode was removed/renamed, either restore the old name in schema.xml or update all clients that send the hint.
  4. 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

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


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)