MyCATApache/Mycat-Server · error · ConfigException
writeHost duplicated!
Error message
writeHost ${hostName} duplicated! What it means
While building a dataHost's writeHost list, XMLSchemaLoader tracks writeHost 'host' attribute values in a HashSet. If two writeHost elements under the same dataHost share the same host name, it throws this ConfigException; write hostnames must be unique within a dataHost so failover/heartbeat logic can address them unambiguously.
Solutions
- Open schema.xml, find the dataHost named in the message, and give each <writeHost> a distinct host attribute value
- Verify any references (e.g., in monitoring scripts or switchType configs) that target the old duplicate name are updated
- If hosts are generated by tooling, add uniqueness enforcement on the host attribute
- Restart MyCat to reload the corrected configuration
Example fix
// before <writeHost host="hostM1" url="10.0.0.1:3306" .../> <writeHost host="hostM1" url="10.0.0.2:3306" .../> // after <writeHost host="hostM1" url="10.0.0.1:3306" .../> <writeHost host="hostM2" url="10.0.0.2:3306" .../>
Defensive patterns
Strategy: validation
Validate before calling
// detect duplicate writeHost names per dataHost
for each dataHost element:
Set<String> seen = new HashSet<>();
NodeList ws = dh.getElementsByTagName("writeHost");
for (int i = 0; i < ws.getLength(); i++) {
String h = ((Element) ws.item(i)).getAttribute("host");
if (!seen.add(h)) throw new IllegalStateException("Duplicate writeHost " + h);
} Type guard
null
Try / catch
try {
schemaLoader.load();
} catch (ConfigException e) {
LOG.error("Duplicate writeHost name: " + e.getMessage());
throw new ConfigurationException("WriteHost host attributes must be unique per dataHost", e);
} Prevention
- Give every writeHost a globally distinct name, not just per-dataHost-unique
- Enforce unique host names in any config-generation script
- Review diffs of schema.xml for copied writeHost lines
When it happens
Trigger: A <dataHost> contains two <writeHost> elements with identical host attributes; createDBHostConf returns a DBHostConfig whose getHostName() is already in writeHostNameSet.
Common situations: Copy-pasting a writeHost for a second master and forgetting to change host="hostM1"; generating configs programmatically without a uniqueness check; backup master mistakenly given the same name as the primary.
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
- dataHost name duplicated!
- readHost duplicated!
- user duplicated!
- table rule duplicated!
- only one rule can defined
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/e4825f624eb972fc.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java:837
}
//读取心跳语句
String heartbeatSQL = element.getElementsByTagName("heartbeat").item(0).getTextContent();
//读取 初始化sql配置,用于oracle
NodeList connectionInitSqlList = element.getElementsByTagName("connectionInitSql");
String initConSQL = null;
if (connectionInitSqlList.getLength() > 0) {
initConSQL = connectionInitSqlList.item(0).getTextContent();
}
//读取writeHost
NodeList writeNodes = element.getElementsByTagName("writeHost");
DBHostConfig[] writeDbConfs = new DBHostConfig[writeNodes.getLength()];
Map<Integer, DBHostConfig[]> readHostsMap = new HashMap<Integer, DBHostConfig[]>(2);
Set<String> writeHostNameSet = new HashSet<String>(writeNodes.getLength());
for (int w = 0; w < writeDbConfs.length; w++) {
Element writeNode = (Element) writeNodes.item(w);
writeDbConfs[w] = createDBHostConf(name, writeNode, dbType, dbDriver, maxCon, minCon, filters, logTime);
if (writeHostNameSet.contains(writeDbConfs[w].getHostName())) {
throw new ConfigException("writeHost " + writeDbConfs[w].getHostName() + " duplicated!");
} else {
writeHostNameSet.add(writeDbConfs[w].getHostName());
}
NodeList readNodes = writeNode.getElementsByTagName("readHost");
//读取对应的每一个readHost
if (readNodes.getLength() != 0) {
DBHostConfig[] readDbConfs = new DBHostConfig[readNodes.getLength()];
Set<String> readHostNameSet = new HashSet<String>(readNodes.getLength());
for (int r = 0; r < readDbConfs.length; r++) {
Element readNode = (Element) readNodes.item(r);
readDbConfs[r] = createDBHostConf(name, readNode, dbType, dbDriver, maxCon, minCon, filters, logTime);
if (readHostNameSet.contains(readDbConfs[r].getHostName())) {
throw new ConfigException("readHost " + readDbConfs[r].getHostName() + " duplicated!");
} else {
readHostNameSet.add(readDbConfs[r].getHostName());
}
}
readHostsMap.put(w, readDbConfs);View on GitHub (pinned to 65f8d8beb7)