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

  1. Check rule.xml for a <tableRule name="..."> whose name exactly matches the table's rule attribute
  2. Fix the spelling of the rule attribute in the <table> element in schema.xml
  3. Add the missing <tableRule> definition to rule.xml
  4. 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

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


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)