MyCATApache/Mycat-Server · error · ConfigException
schema didn't config tables,so you must set dataNode…
Error message
schema ${name} didn't config tables,so you must set dataNode property! What it means
A <schema> element in schema.xml must either declare at least one <table> child or set the dataNode attribute (the default node for un-routed tables). loadSchemas throws this ConfigException when both are missing, because MyCat would have nowhere to route plain tables in that schema.
Solutions
- Add dataNode="dnN" to the <schema> element so it has a default node.
- Alternatively declare the <table> entries the schema should serve.
- If the schema is intentionally empty, remove it entirely from schema.xml.
Example fix
// before (schema.xml) <schema name="TESTDB2"></schema> // after <schema name="TESTDB2" dataNode="dn1"></schema>
Defensive patterns
Strategy: validation
Validate before calling
// Each <schema> must have tables or a dataNode
NodeList schemas = doc.getElementsByTagName("schema");
for (int i = 0; i < schemas.getLength(); i++) {
Element s = (Element) schemas.item(i);
boolean hasDataNode = !s.getAttribute("dataNode").isEmpty();
boolean hasTables = s.getElementsByTagName("table").getLength() > 0;
if (!hasDataNode && !hasTables)
throw new IllegalStateException("schema " + s.getAttribute("name") + " needs dataNode or <table> entries");
} Try / catch
try {
loader = new XMLSchemaLoader();
} catch (ConfigException e) {
if (e.getMessage() != null && e.getMessage().contains("didn't config tables")) {
LOG.error("Schema missing dataNode and tables: {}", e.getMessage());
}
throw e;
} Prevention
- Always set dataNode on schemas that serve plain (non-table-routed) SQL.
- Do not delete all <table> children without also checking dataNode remains set.
- Lint every <schema> element for dataNode-or-tables presence in CI.
When it happens
Trigger: schema.xml has <schema name="X"> with no <table> children and no dataNode attribute; load() -> loadSchemas() evaluates dataNode == null && tables.size() == 0 and throws.
Common situations: Creating an empty placeholder schema expecting tables to be added later; removing all table entries during cleanup while also clearing dataNode; template configs omitting dataNode on non-default schemas.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- schema duplicated!
- table rule duplicated!
- only one rule can defined
- can't find function of name
- table rule coulmns has multi values
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/65a9c6973d5a2166.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java:177
if (dataNode != null && !dataNode.isEmpty()) {
List<String> dataNodeLst = new ArrayList<String>(1);
dataNodeLst.add(dataNode);
checkDataNodeExists(dataNodeLst);
String dataHost = dataNodes.get(dataNode).getDataHost();
defaultDbType = dataHosts.get(dataHost).getDbType();
} else {
dataNode = null;
}
//加载schema下所有tables
Map<String, TableConfig> tables = loadTables(schemaElement);
//判断schema是否重复
if (schemas.containsKey(name)) {
throw new ConfigException("schema " + name + " duplicated!");
}
// 设置了table的不需要设置dataNode属性,没有设置table的必须设置dataNode属性
if (dataNode == null && tables.size() == 0) {
throw new ConfigException(
"schema " + name + " didn't config tables,so you must set dataNode property!");
}
SchemaConfig schemaConfig = new SchemaConfig(name, dataNode,
tables, sqlMaxLimit, "true".equalsIgnoreCase(checkSQLSchemaStr),randomDataNode);
//设定DB类型,这对之后的sql语句路由解析有帮助
if (defaultDbType != null) {
schemaConfig.setDefaultDataNodeDbType(defaultDbType);
if (!"mysql".equalsIgnoreCase(defaultDbType)) {
schemaConfig.setNeedSupportMultiDBType(true);
}
}
// 判断是否有不是mysql的数据库类型,方便解析判断是否启用多数据库分页语法解析
for (TableConfig tableConfig : tables.values()) {
if (isHasMultiDbType(tableConfig)) {
schemaConfig.setNeedSupportMultiDBType(true);View on GitHub (pinned to 65f8d8beb7)