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
- Remove or rename the duplicate <dataNode> definition in schema.xml
- Make range expansions non-overlapping (e.g. dn1$0-5 and dn1$6-9)
- 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
- After editing range expressions, expand them mentally/on paper and check for overlaps
- Keep each dataNode name defined in exactly one place
- Add a CI lint that expands ranges and reports duplicates
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
- table duplicated!
- table duplicated!
- dataNode ' ' is not found!
- dataNode define error ,attribute can't be empty
- dataNode define error ,dnNames.length must…
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)