MyCATApache/Mycat-Server · error · ConfigException

schema duplicated!

Error message

schema ${name} duplicated!

What it means

loadSchemas builds the schemas map keyed by the <schema> element's name attribute. If two schema elements in schema.xml use the same name, the second triggers this ConfigException. Duplicate schema names would break route resolution since a logical schema must map to exactly one configuration.

Solutions

  1. Search schema.xml for duplicate <schema name="..."> entries; merge their <table> definitions into one block or rename one schema.
  2. If generated, fix the generator/template so each schema name is emitted once.
  3. Restart and confirm MyCat loads the configuration.

Example fix

// before (schema.xml)
<schema name="TESTDB" checkSQLschema="false">
  <table name="a" dataNode="dn1" />
</schema>
<schema name="TESTDB">
  <table name="b" dataNode="dn2" />
</schema>
// after
<schema name="TESTDB" checkSQLschema="false">
  <table name="a" dataNode="dn1" />
  <table name="b" dataNode="dn2" />
</schema>
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast on duplicate schema names
Set<String> seen = new HashSet<>();
NodeList schemas = doc.getElementsByTagName("schema");
for (int i = 0; i < schemas.getLength(); i++) {
    String name = ((Element) schemas.item(i)).getAttribute("name");
    if (!seen.add(name)) throw new IllegalStateException("duplicate schema: " + name);
}

Try / catch

try {
    loader = new XMLSchemaLoader();
} catch (ConfigException e) {
    if (e.getMessage() != null && e.getMessage().contains("duplicated!")) {
        LOG.error("Duplicate schema name in schema.xml: {}", e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: schema.xml containing two <schema name="TESTDB"> blocks; load() -> loadSchemas() finds schemas.containsKey(name) true on the second occurrence.

Common situations: Copy-pasting a schema block to add tables but forgetting the first copy; scripted config generation appending schemas; merging schema.xml fragments from different environments.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/1552c993584bff06. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java:172

            }

            // check dataNode already exists or not,看schema标签中是否有datanode
            String defaultDbType = null;
            //校验检查并添加dataNode
            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);
                }
            }

View on GitHub (pinned to 65f8d8beb7)