MyCATApache/Mycat-Server · error · ConfigException
rule is not found!
Error message
rule ${ruleName} is not found! What it means
Thrown by XMLSchemaLoader.loadTable when a <table> element declares a 'rule' attribute whose value does not match any <tableRule name="..."> defined in the schema XML. Mycat resolves table sharding rules by name from the tableRules map built earlier; an unresolvable rule name means the table has no valid partitioning strategy, so startup aborts with ConfigException.
Solutions
- Check rule.xml for a <tableRule name="..."> whose name exactly matches the table's rule attribute
- Fix the spelling of the rule attribute in the <table> element in schema.xml
- Add the missing <tableRule> definition to rule.xml
- If the table needs no sharding, remove the rule attribute entirely (optionally set ruleRequired="false")
Example fix
// before (schema.xml) <table name="orders" dataNode="dn1" rule="ordrRule" /> // after <table name="orders" dataNode="dn1" rule="orderRule" /> <!-- matches <tableRule name="orderRule"> in rule.xml -->
Defensive patterns
Strategy: validation
Validate before calling
// before starting Mycat, verify every table rule reference exists
Set<String> definedRules = collectTableRuleNames("rule.xml");
for (Element t : schemaTables("schema.xml")) {
if (t.hasAttribute("rule") && !definedRules.contains(t.getAttribute("rule")))
throw new IllegalStateException("Undefined rule: " + t.getAttribute("rule"));
} Try / catch
try {
configLoader.load();
} catch (ConfigException e) {
if (e.getMessage().contains("is not found") && e.getMessage().startsWith("rule")) {
log.error("Fix schema.xml <table rule=...> to match a <tableRule name=...> in rule.xml", e);
}
throw e; // config errors are fatal, do not swallow
} Prevention
- Keep rule names in schema.xml and rule.xml in sync; diff them in CI
- Grep schema.xml rule attributes against rule.xml tableRule names at build time
- Never rename a tableRule without updating all referencing tables
When it happens
Trigger: A <table name="t" rule="ruleX"> entry in schema.xml where 'ruleX' is not defined as a <tableRule name="ruleX"> in rule.xml, or the rule name is misspelled/renamed while tables still reference the old name.
Common situations: Typo in the rule attribute; rule defined in rule.xml but schema.xml references a stale name after a refactor; copy-pasting table configs from another project with different rule names; rule declared after use in a merged config.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- can't find function of name
- dataNode ' ' is not found!
- dataNode reference dataHost: not exists!
- dataHost not exists
- ConfigException wrapping cause (no message)
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/b3a714353288a5ee.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java:367
//记录是否需要加返回结果集限制,默认需要加
boolean needAddLimit = true;
if (tableElement.hasAttribute("needAddLimit")) {
needAddLimit = Boolean.parseBoolean(tableElement.getAttribute("needAddLimit"));
}
//记录type,是否为global
String tableTypeStr = tableElement.hasAttribute("type") ? tableElement.getAttribute("type") : null;
int tableType = TableConfig.TYPE_GLOBAL_DEFAULT;
if ("global".equalsIgnoreCase(tableTypeStr)) {
tableType = TableConfig.TYPE_GLOBAL_TABLE;
}
//记录dataNode,就是分布在哪些dataNode上
String dataNode = tableElement.getAttribute("dataNode");
TableRuleConfig tableRule = null;
if (tableElement.hasAttribute("rule")) {
String ruleName = tableElement.getAttribute("rule");
tableRule = tableRules.get(ruleName);
if (tableRule == null) {
throw new ConfigException("rule " + ruleName + " is not found!");
}
}
boolean ruleRequired = false;
//记录是否绑定有分片规则
if (tableElement.hasAttribute("ruleRequired")) {
ruleRequired = Boolean.parseBoolean(tableElement.getAttribute("ruleRequired"));
}
if (tableNames == null) {
throw new ConfigException("table name is not found!");
}
//distribute函数,重新编排dataNode
String distPrex = "distribute(";
boolean distTableDns = dataNode.startsWith(distPrex);
if (distTableDns) {
dataNode = dataNode.substring(distPrex.length(), dataNode.length() - 1);
}View on GitHub (pinned to 65f8d8beb7)