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

  1. Add dataNode="dnN" to the <schema> element so it has a default node.
  2. Alternatively declare the <table> entries the schema should serve.
  3. 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

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


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)