MyCATApache/Mycat-Server · error · ConfigException
table rule duplicated!
Error message
table rule ${name} duplicated! What it means
XMLRuleLoader.loadTableRules parses <tableRule> elements from rule.xml and stores them in a map keyed by the name attribute. If two tableRule elements share the same name, the second insertion is rejected with this ConfigException. The loader is fail-fast: duplicate rule names would make routing resolution ambiguous, so startup aborts.
Solutions
- Open rule.xml and search for duplicate <tableRule name="..."> entries; remove or rename the redundant one.
- If two rules need similar config, give each a unique name and reference the correct one in each table's rule attribute.
- After fixing, restart or reload MyCat config to confirm startup completes.
Example fix
// before (rule.xml) <tableRule name="order-rule"> <rule><columns>id</columns><algorithm>mod-long</algorithm></rule> </tableRule> <tableRule name="order-rule"> <rule><columns>cust_id</columns><algorithm>hash-int</algorithm></rule> </tableRule> // after <tableRule name="order-rule"> <rule><columns>id</columns><algorithm>mod-long</algorithm></rule> </tableRule> <tableRule name="order-cust-rule"> <rule><columns>cust_id</columns><algorithm>hash-int</algorithm></rule> </tableRule>
Defensive patterns
Strategy: validation
Validate before calling
// Before deploying rule.xml, fail fast on duplicate tableRule names
Set<String> seen = new HashSet<>();
NodeList rules = doc.getElementsByTagName("tableRule");
for (int i = 0; i < rules.getLength(); i++) {
String name = ((Element) rules.item(i)).getAttribute("name");
if (!seen.add(name)) throw new IllegalStateException("duplicate tableRule: " + name);
} Try / catch
try {
configLoader.load();
} catch (ConfigException e) {
if (e.getMessage().contains("duplicated!")) {
LOG.error("rule.xml has duplicate definitions: {}", e.getMessage());
throw new ConfigValidationException(e);
}
throw e;
} Prevention
- Keep one canonical rule.xml under version control; never hand-merge fragments.
- Add a CI step (xmllint or a small script) that asserts unique tableRule names.
- When adding a rule, search the file for the name first.
When it happens
Trigger: Starting MyCat with a rule.xml (or overlapping rule.xml files) that defines two <tableRule name="X"> elements with the same name attribute; load() -> loadTableRules() hits tableRules.containsKey(name) on the second definition.
Common situations: Hand-editing rule.xml and copy-pasting a tableRule block without renaming it; merging config fragments from different environments; a hot-reload that appends a new rule without removing the old one.
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
- rule function duplicated!
- schema duplicated!
- dataHost define error,some attributes of this element is…
- only one rule can defined
- can't find function of name
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/a83a478b7b371ba3.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/config/loader/xml/XMLRuleLoader.java:133
* <rule>
* <columns>create_date</columns>
* <algorithm>partbymonth</algorithm>
* </rule>
* </tableRule>
* @param root
* @throws SQLSyntaxErrorException
*/
private void loadTableRules(Element root) throws SQLSyntaxErrorException {
//获取每个tableRule标签
NodeList list = root.getElementsByTagName("tableRule");
for (int i = 0, n = list.getLength(); i < n; ++i) {
Node node = list.item(i);
if (node instanceof Element) {
Element e = (Element) node;
//先判断是否重复
String name = e.getAttribute("name");
if (tableRules.containsKey(name)) {
throw new ConfigException("table rule " + name
+ " duplicated!");
}
//获取rule标签
NodeList ruleNodes = e.getElementsByTagName("rule");
int length = ruleNodes.getLength();
if (length > 1) {
throw new ConfigException("only one rule can defined :"
+ name);
}
//目前只处理第一个,未来可能有多列复合逻辑需求
//RuleConfig是保存着rule与function对应关系的对象
RuleConfig rule = loadRule((Element) ruleNodes.item(0));
String funName = rule.getFunctionName();
//判断function是否存在,获取function
AbstractPartitionAlgorithm func = functions.get(funName);
if (func == null) {
throw new ConfigException("can't find function of name :"
+ funName);
View on GitHub (pinned to 65f8d8beb7)