MyCATApache/Mycat-Server · error · SQLNonTransientException
can't find table define in schema
Error message
can't find table define in schema {tableName} schema:{schemaName} What it means
Thrown during route calculation when the table name extracted from the SQL (routeUnit) is not present in the schema's configured tables (schema.getTables()). Mycat can only route tables declared in schema.xml.
Solutions
- Add the table to schema.xml as a <table> entry with correct dataNode/rule, then reload config
- Check table-name case: ensure the SQL name matches the schema.xml entry (Mycat matches via upper-cased names)
- Verify the client connected to the correct Mycat logical schema (use fully qualified db.table or SET_SCHEMA)
- If the table is intentionally unsharded, ensure it's still declared with a dataNode
Example fix
// before (schema.xml missing table) <schema name="TESTDB"> <table name="orders" dataNode="dn1,dn2" rule="mod-rule"/> </schema> // after (declare the missing table) <schema name="TESTDB"> <table name="orders" dataNode="dn1,dn2" rule="mod-rule"/> <table name="order_item" dataNode="dn1,dn2" rule="mod-rule"/> </schema>
Defensive patterns
Strategy: validation
Validate before calling
boolean exists = schema.getTables().containsKey(tableName.trim().toUpperCase());
if (!exists) throw new IllegalArgumentException("table not in schema.xml: " + tableName); Try / catch
try { rrs = route(...); } catch (SQLNonTransientException e) { if (e.getMessage().startsWith("can't find table define")) { LOG.warn("declare table in schema.xml: " + e.getMessage()); } throw e; } Prevention
- Keep schema.xml table declarations in sync with application DDL
- Use consistent uppercase naming for logical tables
- Validate schema.xml with a startup smoke test that routes one query per table
When it happens
Trigger: Executing SQL that references a table not declared in schema.xml (or with a case mismatch after uppercasing); the logical schema in the connection does not contain the table definition.
Common situations: Table missing from schema.xml <table> entries; case-sensitivity mismatch (Mycat upper-cases table names); connecting to a schema in which the table wasn't configured; typo in table name.
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
- SelfCheck### user all node is empty!
- SelfCheck### users node within the item is empty!
- SelfCheck### user refered schemas is empty!
- SelfCheck### schema
- SelfCheck### schema all node is empty!
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/cf51828542ff465d.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/util/RouterUtil.java:1375
/**
*
* 单表路由
*/
public static RouteResultset tryRouteForOneTable(SchemaConfig schema, DruidShardingParseInfo ctx,
RouteCalculateUnit routeUnit, String tableName, RouteResultset rrs, boolean isSelect,
LayerCachePool cachePool) throws SQLNonTransientException {
if (isNoSharding(schema, tableName)) {
return routeToSingleNode(rrs, schema.getDataNode(), ctx.getSql());
}
TableConfig tc = schema.getTables().get(tableName);
if(tc == null) {
String msg = "can't find table define in schema " + tableName + " schema:" + schema.getName();
LOGGER.warn(msg);
throw new SQLNonTransientException(msg);
}
Map<String, Map<String, Set<ColumnRoutePair>>> tablesAndConditions = routeUnit.getTablesAndConditions();
if(tc.isDistTable()){
Set<String> keySet = tablesAndConditions.keySet();
//Map.Entry<String, Map<String, Set<ColumnRoutePair>>> entry = (Entry<String, Map<String, Set<ColumnRoutePair>>>) tablesAndConditions.get(keySet.toArray()[0]);
return routeToDistTableNode(schema,rrs,ctx.getSql(), tablesAndConditions, cachePool,isSelect, null);
}
if(tc.isGlobalTable()) {//全局表
if(isSelect) {
// global select ,not cache route result
rrs.setCacheAble(false);
return routeToSingleNode(rrs, getAliveRandomDataNode(tc)/*getRandomDataNode(tc)*/, ctx.getSql());
} else {//insert into 全局表的记录
return routeToMultiNode(false, rrs, tc.getDataNodes(), ctx.getSql(),true);
}
} else {//单表或者分库表
View on GitHub (pinned to 65f8d8beb7)