MyCATApache/Mycat-Server · error · ConfigException

dataNode duplicated!

Error message

dataNode ${name} duplicated!

What it means

Thrown by XMLSchemaLoader.createDataNode when two <dataNode> definitions expand to the same name. The dataNodes map is keyed by name; a duplicate would silently overwrite host/database bindings, so schema loading fails.

Solutions

  1. Remove or rename the duplicate <dataNode> definition in schema.xml
  2. Make range expansions non-overlapping (e.g. dn1$0-5 and dn1$6-9)
  3. Search schema.xml for the reported name to find all conflicting declarations

Example fix

// before (schema.xml)
<dataNode name="dn1$0-5" dataHost="h1" database="db1" />
<dataNode name="dn1$3-7" dataHost="h1" database="db1" /> <!-- overlaps 3-5 -->
// after
<dataNode name="dn1$0-5" dataHost="h1" database="db1" />
<dataNode name="dn1$6-9" dataHost="h1" database="db1" />
Defensive patterns

Strategy: validation

Validate before calling

// detect overlapping dataNode names (including ranges) before load
Set<String> seen = new HashSet<>();
for (Element dn : dataNodeElements("schema.xml")) {
    for (String n : expand(dn.getAttribute("name"))) { // expand $x-y ranges
        if (!seen.add(n))
            throw new IllegalStateException("Duplicate dataNode: " + n);
    }
}

Try / catch

try {
    configLoader.load();
} catch (ConfigException e) {
    if (e.getMessage().contains("dataNode") && e.getMessage().contains("duplicated!")) {
        String name = extractBetween(e.getMessage(), "dataNode ", " duplicated!");
        log.error("dataNode '" + name + "' declared more than once", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Two <dataNode> elements with the same name attribute; overlapping range expansions like dn1$0-5 in one element and dn1$3-7 in another; the same dataNode declared in multiple schema files.

Common situations: Copy-pasting dataNode blocks; range expansions that overlap; merging configs from different environments that both define dn1..dn10.

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/183c823d9ef9f682. Report an issue: GitHub.

Appendix: source

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

        List<String[]> mhdList = new ArrayList<>();
        for (int i = 0; i < hostStrings.length; i++) {
            String hostString = hostStrings[i];
            for (int i1 = 0; i1 < databases.length; i1++) {
                String database = databases[i1];
                String[] hd = new String[2];
                hd[0] = hostString;
                hd[1] = database;
                mhdList.add(hd);
            }
        }
        return mhdList;
    }

    private void createDataNode(String dnName, String database, String host) {

        DataNodeConfig conf = new DataNodeConfig(dnName, database, host);
        if (dataNodes.containsKey(conf.getName())) {
            throw new ConfigException("dataNode " + conf.getName() + " duplicated!");
        }

        if (!dataHosts.containsKey(host)) {
            throw new ConfigException("dataNode " + dnName + " reference dataHost:" + host + " not exists!");
        }

        dataHosts.get(host).addDataNode(conf.getName());
        dataNodes.put(conf.getName(), conf);
    }

    private boolean empty(String dnName) {
        return dnName == null || dnName.length() == 0;
    }

    private DBHostConfig createDBHostConf(String dataHost, Element node,
                                          String dbType, String dbDriver, int maxCon, int minCon, String filters, long logTime) {

        String nodeHost = node.getAttribute("host");

View on GitHub (pinned to 65f8d8beb7)