MyCATApache/Mycat-Server · error
ER_PARSE_ERROR
ER_PARSE_ERROR
Error message
msg == null ? e.getClass().getSimpleName() : msg
What it means
ServerConnection.routeSQL() wraps SQL routing in a catch-all: any exception raised while parsing/routing a query through the RouterService is converted to a MySQL ER_PARSE_ERROR packet sent back to the client. The message is the exception's getMessage(), or the exception class's simple name when the message is null. It is a generic 'your SQL could not be routed/parsed by Mycat' reply rather than a true MySQL parser error.
Solutions
- Read the server log (LOGGER.warn prints this + sql + full stack trace) to find the real underlying exception and its cause.
- Fix the SQL to use syntax supported by Mycat's router, or adjust schema/rule configuration for the referenced tables.
- If the message is just a class name (null message), inspect the stack trace for an NPE from missing schema/rule config and complete schema.xml/rule.xml.
Example fix
// before: incomplete sharding config causes NPE inside route() SELECT * FROM order_detail WHERE id=1 // table missing in schema.xml -> NPE -> ER_PARSE_ERROR 'NullPointerException' // after <!-- schema.xml: declare the table so routing succeeds --> <table name="order_detail" dataNode="dn1" />
Defensive patterns
Strategy: try-catch
Validate before calling
// before sending: check the statement is non-empty and table is declared in schema
String sql = "SELECT * FROM order_detail WHERE id=1";
if (sql == null || sql.trim().isEmpty()) throw new IllegalArgumentException("empty SQL");
// verify table exists in Mycat schema config (e.g. via SHOW TABLES on manager port)
boolean declared = mycatSchemaTables.contains(resolveTableName(sql));
if (!declared) { /* fix schema.xml before routing */ } Try / catch
try {
routeSQL(sql, type);
} catch (Exception e) {
// client sees ER_PARSE_ERROR; consult server log for the real cause
LOGGER.error("route failed for sql: " + sql, e);
String detail = (e.getMessage() != null) ? e.getMessage() : e.getClass().getSimpleName();
throw new RuntimeException("SQL routing failed: " + detail, e);
} Prevention
- Always check the Mycat server log, not just the client error packet, since ER_PARSE_ERROR masks the real exception.
- Keep schema.xml/rule.xml in sync with every table referenced by application SQL.
- Test new SQL against Mycat with EXPLAIN via the manager port before deploying.
- Avoid syntax known to be unsupported by Mycat's Druid-based parser.
When it happens
Trigger: Any Exception thrown inside routeSQL while calling MycatServer.getInstance().getRouterservice().route(...), e.g. syntax Mycat's SQL parser cannot handle, unknown table/schema in sharding rules, or a routing rule throwing; also when e.getMessage() is null (e.g. NPE) the client sees just the class name like 'NullPointerException'.
Common situations: Mycat-specific or non-standard SQL syntax the embedded Druid parser rejects; queries against tables lacking schemaConfig/sharding config; NPEs from incomplete schema.xml configuration being surfaced as parse errors; version upgrades where the router became stricter.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- Multi statements is not supported,use single statement…
- ER_PARSE_ERROR
- not a query sql statement
- Can't identify the operation of of where
- schema: ,table: ,sql: is not allowed,because table is…
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/eb36eb30a3d205bc.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/server/ServerConnection.java:328
writeErrMessage(ErrorCode.ERR_BAD_LOGICDB,
"Unknown MyCAT Database '" + db + "'");
return null;
}
// 路由计算
RouteResultset rrs = null;
try {
rrs = MycatServer
.getInstance()
.getRouterservice()
.route(MycatServer.getInstance().getConfig().getSystem(),
schema, type, sql, this.charset, this);
} catch (Exception e) {
StringBuilder s = new StringBuilder();
LOGGER.warn(s.append(this).append(sql).toString() + " err:" + e.toString(),e);
String msg = e.getMessage();
writeErrMessage(ErrorCode.ER_PARSE_ERROR, msg == null ? e.getClass().getSimpleName() : msg);
return null;
}
return rrs;
}
public void routeEndExecuteSQL(String sql, final int type, final SchemaConfig schema) {
// 路由计算
RouteResultset rrs = null;
try {
rrs = MycatServer
.getInstance()
.getRouterservice()
.route(MycatServer.getInstance().getConfig().getSystem(),
schema, type, sql, this.charset, this);
View on GitHub (pinned to 65f8d8beb7)