MyCATApache/Mycat-Server · error · SQLNonTransientException

"can't find hint datanode:" + hintSQLValue

Error message

"can't find hint datanode:" + hintSQLValue

What it means

The /*datanode=...*/ hint routes a statement to one specific data node. HintDataNodeHandler looks up hintSQLValue in MycatServer's configured dataNodes map; if no data node with that name exists, it throws SQLNonTransientException because the hinted route cannot be resolved.

Solutions

  1. Fix the hint value to match an existing <dataNode name="..."> in schema.xml (check exact spelling/case)
  2. List available nodes (config dump / show @@datanode) and use one of those names
  3. If the config changed, update application code or hint-emitting middleware to the new data node names

Example fix

-- before
/*datanode=dn_2*/ SELECT * FROM t_user WHERE id=1;
-- after (matches schema.xml <dataNode name="dn2">)
/*datanode=dn2*/ SELECT * FROM t_user WHERE id=1;
Defensive patterns

Strategy: validation

Validate before calling

Set<String> valid = mycatConfig.getDataNodes().keySet();
if (!valid.contains(hintValue)) throw new IllegalArgumentException("unknown datanode: " + hintValue);

Type guard

if (hintValue != null && MycatServer.getInstance().getConfig().getDataNodes().containsKey(hintValue)) { ... }

Try / catch

try { queryWithHint(hintValue, sql); } catch (SQLNonTransientException e) { if (e.getMessage().startsWith("can't find hint datanode")) { refreshHintTargets(); } else throw e; }

Prevention

When it happens

Trigger: Sending a hint like `/* datanode=dn2 */ SELECT ...` (or HintManager.useDataNode(...)) where 'dn2' is not a <dataNode> name in Mycat's config, or the config was reloaded/renamed so the name no longer exists.

Common situations: Typo in the hint value; dataNode renamed in schema.xml after application code/SQL was already deployed; hint copied from another environment with different node names.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/fa037f0c6ca0b60f. 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)