MyCATApache/Mycat-Server · error · SQLNonTransientException
"can't find table define in schema " + tableName + "…
Error message
"can't find table define in schema " + tableName + " schema:" + schema.getName()
What it means
The insert parser looks up the table name from the INSERT statement in the schema configuration (schema.xml tables map). If no TableConfig exists for that table, Mycat cannot determine datanodes/sharding rules, so it throws SQLNonTransientException.
Solutions
- Add a <table> entry for the table in schema.xml (with its datanodes and rule) and reload/restart Mycat
- Verify the client connected to the intended schema (schema name in the message)
- Check the table name spelling and case matches schema.xml exactly (names are uppercased before lookup)
- If the table lives only on one node, ensure it is still declared in schema.xml, or route it via a schema entry with no rule
Example fix
// before (schema.xml) <schema name="db"> <table name="t1" dataNode="dn1"/> </schema> // after <schema name="db"> <table name="t1" dataNode="dn1"/> <table name="t2" dataNode="dn1,dn2" rule="rule1"/> </schema>
Defensive patterns
Strategy: validation
Validate before calling
// verify table is declared before inserting
SchemaConfig schema = MycatServer.getInstance().getConfig().getSchemas().get(currentSchema);
String table = sqlTableName.toUpperCase();
if (schema == null || !schema.getTables().containsKey(table)) {
throw new IllegalStateException("Table not defined in schema.xml: " + table);
} Type guard
static TableConfig requireTable(SchemaConfig schema, String tableName) {
TableConfig tc = schema.getTables().get(tableName);
if (tc == null) throw new IllegalStateException("can't find table define in schema " + tableName);
return tc;
} Try / catch
try {
routeResult = route(insertSql);
} catch (SQLNonTransientException e) {
if (e.getMessage().startsWith("can't find table define in schema")) {
throw new ConfigurationException("Declare the table in schema.xml or connect to the correct schema", e);
}
throw e;
} Prevention
- Keep schema.xml in sync with backend DDL; add every routable table
- Verify the JDBC URL targets the intended Mycat schema
- Normalize table-name case to match schema.xml declarations
- Run a startup checklist that SELECTs each expected table through Mycat
When it happens
Trigger: Executing INSERT INTO <tbl> ... where <tbl> (uppercased, backquotes stripped) is absent from schema.getTables(); typically the table is not declared in schema.xml or the wrong logical schema is targeted by the connection.
Common situations: Table added to backend MySQL but not to schema.xml; connecting to the wrong Mycat schema; case-sensitivity mismatch between SQL table name and schema.xml table declaration; 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
- can't find table define of in schema:
- CachePoolFactory not defined for type
- can't find cache pool
- SelfCheck### user refered schemas is empty!
- schema duplicated!
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/a013753be2c9923d.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/parser/druid/impl/DruidInsertParser.java:64
*/
@Override
public void statementParse(SchemaConfig schema, RouteResultset rrs, SQLStatement stmt) throws SQLNonTransientException {
MySqlInsertStatement insert = (MySqlInsertStatement)stmt;
String tableName = StringUtil.removeBackquote(insert.getTableName().getSimpleName()).toUpperCase();
ctx.addTable(tableName);
if(RouterUtil.isNoSharding(schema,tableName)) {//整个schema都不分库或者该表不拆分
RouterUtil.routeForTableMeta(rrs, schema, tableName, rrs.getStatement());
rrs.setFinishedRoute(true);
return;
}
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);
} else {
//childTable的insert直接在解析过程中完成路由
if (tc.isChildTable()) {
parserChildTable(schema, rrs, tableName, insert);
return;
}
String partitionColumn = tc.getPartitionColumn();
if(partitionColumn != null) {//分片表
//拆分表必须给出column list,否则无法寻找分片字段的值
if(insert.getColumns() == null || insert.getColumns().size() == 0) {
throw new SQLSyntaxErrorException("partition table, insert must provide ColumnList");
}
//批量insert
if(isMultiInsert(insert)) {
// String msg = "multi insert not provided" ;View on GitHub (pinned to 65f8d8beb7)