{"record":{"id":"6e4b70af00f28886","repo":"MyCATApache/Mycat-Server","slug":"readhost-hostname-duplicated","errorCode":null,"errorMessage":"readHost ${hostName} duplicated!","messagePattern":"readHost (.+?) duplicated!","errorType":"exception","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java","lineNumber":850,"sourceCode":"            Set<String> writeHostNameSet = new HashSet<String>(writeNodes.getLength());\n            for (int w = 0; w < writeDbConfs.length; w++) {\n                Element writeNode = (Element) writeNodes.item(w);\n                writeDbConfs[w] = createDBHostConf(name, writeNode, dbType, dbDriver, maxCon, minCon, filters, logTime);\n                if (writeHostNameSet.contains(writeDbConfs[w].getHostName())) {\n                    throw new ConfigException(\"writeHost \" + writeDbConfs[w].getHostName() + \" duplicated!\");\n                } else {\n                    writeHostNameSet.add(writeDbConfs[w].getHostName());\n                }\n                NodeList readNodes = writeNode.getElementsByTagName(\"readHost\");\n                //读取对应的每一个readHost\n                if (readNodes.getLength() != 0) {\n                    DBHostConfig[] readDbConfs = new DBHostConfig[readNodes.getLength()];\n                    Set<String> readHostNameSet = new HashSet<String>(readNodes.getLength());\n                    for (int r = 0; r < readDbConfs.length; r++) {\n                        Element readNode = (Element) readNodes.item(r);\n                        readDbConfs[r] = createDBHostConf(name, readNode, dbType, dbDriver, maxCon, minCon, filters, logTime);\n                        if (readHostNameSet.contains(readDbConfs[r].getHostName())) {\n                            throw new ConfigException(\"readHost \" + readDbConfs[r].getHostName() + \" duplicated!\");\n                        } else {\n                            readHostNameSet.add(readDbConfs[r].getHostName());\n                        }\n                    }\n                    readHostsMap.put(w, readDbConfs);\n                }\n            }\n\n            DataHostConfig hostConf = new DataHostConfig(name, dbType, dbDriver,\n                    writeDbConfs, readHostsMap, switchType, slaveThreshold, tempReadHostAvailable);\n\n            hostConf.setMaxCon(maxCon);\n            hostConf.setMinCon(minCon);\n            hostConf.setBalance(balance);\n            hostConf.setBalanceType(balanceType);\n            hostConf.setWriteType(writeType);\n            hostConf.setHearbeatSQL(heartbeatSQL);\n            hostConf.setConnectionInitSql(initConSQL);","sourceCodeStart":832,"sourceCodeEnd":868,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java#L832-L868","documentation":"Within a writeHost's <readHost> children, XMLSchemaLoader collects readHost 'host' attribute names into a HashSet and throws this ConfigException if the same host name appears twice under one writeHost. Read hostnames must be unique within their writeHost scope so the read pool can distinguish replicas.","triggerScenarios":"A <writeHost> element has two <readHost> children with the same host attribute; createDBHostConf produces a DBHostConfig whose getHostName() already exists in readHostNameSet.","commonSituations":"Copy-pasting a readHost line to add another replica without changing host=\"hostS1\"; scripted replica provisioning reusing names; mistakenly nesting the same readHost under multiple writeHosts with identical names.","solutions":["Locate the writeHost in schema.xml whose readHost children collide and assign each readHost a unique host attribute (e.g., hostS1, hostS2)","Note uniqueness is scoped per writeHost in this check, but use globally distinct names to be safe","If readHosts are provisioned by automation, enforce unique names there","Restart MyCat and confirm the config loads"],"exampleFix":"// before\n<readHost host=\"hostS1\" url=\"10.0.1.1:3306\" .../>\n<readHost host=\"hostS1\" url=\"10.0.1.2:3306\" .../>\n// after\n<readHost host=\"hostS1\" url=\"10.0.1.1:3306\" .../>\n<readHost host=\"hostS2\" url=\"10.0.1.2:3306\" .../>","handlingStrategy":"validation","validationCode":"// detect duplicate readHost names under each writeHost\nfor each writeHost element:\n  Set<String> seen = new HashSet<>();\n  NodeList rs = wh.getElementsByTagName(\"readHost\");\n  for (int i = 0; i < rs.getLength(); i++) {\n      String h = ((Element) rs.item(i)).getAttribute(\"host\");\n      if (!seen.add(h)) throw new IllegalStateException(\"Duplicate readHost \" + h);\n  }","typeGuard":"null","tryCatchPattern":"try {\n    schemaLoader.load();\n} catch (ConfigException e) {\n    LOG.error(\"Duplicate readHost name: \" + e.getMessage());\n    throw new ConfigurationException(\"ReadHost host attributes must be unique per writeHost\", e);\n}","preventionTips":["Use a replica naming scheme (hostS1..hostSn) and increment when adding replicas","Validate generated replica configs for name uniqueness","Check nesting: readHost names are scoped under their writeHost"],"tags":["configuration","xml","duplicate"],"backgroundTag":"conflicting-config-options","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}