{"record":{"id":"cf2f88bbe7a141c6","repo":"MyCATApache/Mycat-Server","slug":"user-name-duplicated","errorCode":null,"errorMessage":"user ${name} duplicated!","messagePattern":"user (.+?) duplicated!","errorType":"exception","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/config/loader/xml/XMLServerLoader.java","lineNumber":244,"sourceCode":"\t\t\t\t}\n\n\t\t\t\tString readOnly = (String) props.get(\"readOnly\");\n\t\t\t\tif (null != readOnly) {\n\t\t\t\t\tuser.setReadOnly(Boolean.parseBoolean(readOnly));\n\t\t\t\t}\n\n\n\t\t\t\tString schemas = (String) props.get(\"schemas\");\n                if (schemas != null) {\n                    String[] strArray = SplitUtil.split(schemas, ',', true);\n                    user.setSchemas(new HashSet<String>(Arrays.asList(strArray)));\n                }\n\n                //加载用户 DML 权限\n                loadPrivileges(user, e);\n\n                if (users.containsKey(name)) {\n                    throw new ConfigException(\"user \" + name + \" duplicated!\");\n                }\n                users.put(name, user);\n            }\n        }\n    }\n\n    private void loadPrivileges(UserConfig userConfig, Element node) {\n\n    \tUserPrivilegesConfig privilegesConfig = new UserPrivilegesConfig();\n\n    \tNodeList privilegesNodes = node.getElementsByTagName(\"privileges\");\n    \tint privilegesNodesLength = privilegesNodes.getLength();\n\t\tfor (int i = 0; i < privilegesNodesLength; ++i) {\n\t\t\tElement privilegesNode = (Element) privilegesNodes.item(i);\n\t\t\tString check = privilegesNode.getAttribute(\"check\");\n         \tif (null != check) {\n         \t\tprivilegesConfig.setCheck(Boolean.valueOf(check));\n\t\t\t}","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/config/loader/xml/XMLServerLoader.java#L226-L262","documentation":"XMLServerLoader.loadUsers iterates <user> elements in server.xml and stores them keyed by the name attribute. If a second <user> reuses a name already in the users map, it throws this ConfigException because user names must be unique — each name identifies exactly one account with its own password and privileges. Startup aborts.","triggerScenarios":"Loading server.xml where two <user name=\"root\"> (or any repeated name) elements exist; duplicates may also come from merged or included server.xml fragments.","commonSituations":"Copy-pasting a user block to create a second account and forgetting to rename it; merging environment configs that both define 'root'; generated configs re-emitting the same user.","solutions":["Search server.xml for duplicate <user name=\"...\"> elements and rename the extra account to a unique name (then update client connection strings that use it)","Remove genuinely redundant duplicate user blocks","If duplicates come from config merging tooling, deduplicate users before deployment and add a uniqueness check","Restart MyCat and confirm server.xml loads"],"exampleFix":"// before\n<user name=\"root\">...</user>\n<user name=\"root\">...</user>\n// after\n<user name=\"root\">...</user>\n<user name=\"app\">...</user>","handlingStrategy":"validation","validationCode":"// detect duplicate user names in server.xml\nSet<String> seen = new HashSet<>();\nNodeList us = doc.getElementsByTagName(\"user\");\nfor (int i = 0; i < us.getLength(); i++) {\n    String n = ((Element) us.item(i)).getAttribute(\"name\");\n    if (!seen.add(n)) throw new IllegalStateException(\"Duplicate user: \" + n);\n}","typeGuard":"null","tryCatchPattern":"try {\n    serverLoader.load();\n} catch (ConfigException e) {\n    LOG.error(\"Duplicate user name in server.xml: \" + e.getMessage());\n    throw new ConfigurationException(\"User names must be unique\", e);\n}","preventionTips":["Rename copied user blocks immediately after pasting","Deduplicate users when merging environment configs","Lint server.xml user-name uniqueness in CI"],"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"}