MyCATApache/Mycat-Server · error · ConfigException
only one rule can defined
Error message
only one rule can defined :${name} What it means
Within one <tableRule> element, loadTableRules counts nested <rule> child elements. MyCat only supports a single rule (sharding column/algorithm pair) per tableRule, so more than one <rule> tag throws this ConfigException. The comment notes multi-column composite rules are planned but not implemented in this version.
Solutions
- Keep exactly one <rule> element per <tableRule> and restart.
- If multi-column sharding is needed, use an algorithm that itself handles composite keys (e.g. a custom AbstractPartitionAlgorithm fed one concatenated column or a complex sharding function) instead of multiple <rule> tags.
- Upgrade to a MyCat version that supports multi-column rules if the requirement is hard.
Example fix
// before (rule.xml) <tableRule name="order-rule"> <rule><columns>id</columns><algorithm>mod-long</algorithm></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>
Defensive patterns
Strategy: validation
Validate before calling
// Assert each tableRule has exactly one <rule> child before deployment
NodeList tableRules = doc.getElementsByTagName("tableRule");
for (int i = 0; i < tableRules.getLength(); i++) {
Element tr = (Element) tableRules.item(i);
if (tr.getElementsByTagName("rule").getLength() != 1)
throw new IllegalStateException("tableRule " + tr.getAttribute("name") + " must define exactly one <rule>");
} Try / catch
try {
ruleLoader.load();
} catch (ConfigException e) {
if (e.getMessage().startsWith("only one rule can defined")) {
LOG.error("Multi-rule tableRule not supported: {}", e.getMessage());
}
throw e;
} Prevention
- Document that this MyCat version supports one rule per tableRule.
- Handle multi-column sharding inside the algorithm class, not via extra <rule> tags.
- Validate rule.xml in CI before shipping configs.
When it happens
Trigger: A rule.xml tableRule block containing two or more <rule> children, e.g. trying to declare sharding on two columns; load() -> loadTableRules() sees ruleNodes.getLength() > 1.
Common situations: Developers attempting composite/multi-column sharding by adding a second <rule> entry; copy-pasted example configs from newer MyCat forks that support multiple rules; merged XML fragments.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- table rule coulmns has multi values
- can't find function of name
- rule function duplicated!
- nameSuffix , require name parameter cannot multiple breaks!
- table rule duplicated!
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/ff68c6b1c238eb19.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/config/loader/xml/XMLRuleLoader.java:140
*/
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);
}
rule.setRuleAlgorithm(func);
//保存到tableRules
tableRules.put(name, new TableRuleConfig(name, rule));
}
}
}
View on GitHub (pinned to 65f8d8beb7)