MyCATApache/Mycat-Server · error · ConfigException

can't find function of name

Error message

can't find function of name :${funName}

What it means

Each tableRule's <algorithm> element names a sharding function declared in a <function> block. loadTableRules looks the function name up in the functions map; if absent, it throws this ConfigException. This means the rule references a function that was never defined (or failed to load) in rule.xml.

Solutions

  1. Add the missing <function name="..." class="..."> block to rule.xml, matching the tableRule's algorithm value exactly.
  2. Check spelling/case of the algorithm name against the function's name attribute.
  3. Scan the log for an earlier createFunction/reflection error indicating the function block failed to load.

Example fix

// before (rule.xml)
<tableRule name="order-rule">
  <rule><columns>id</columns><algorithm>mod-long</algorithm></rule>
</tableRule>
<!-- <function name="mod-long" .../> missing -->
// after
<tableRule name="order-rule">
  <rule><columns>id</columns><algorithm>mod-long</algorithm></rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
  <property name="count">4</property>
</function>
Defensive patterns

Strategy: validation

Validate before calling

// Verify every tableRule algorithm references a defined function name
Set<String> fnNames = new HashSet<>();
NodeList fns = doc.getElementsByTagName("function");
for (int i = 0; i < fns.getLength(); i++)
    fnNames.add(((Element) fns.item(i)).getAttribute("name"));
NodeList rules = doc.getElementsByTagName("tableRule");
for (int i = 0; i < rules.getLength(); i++) {
    Element tr = (Element) rules.item(i);
    String algo = ((Element) tr.getElementsByTagName("rule").item(0))
        .getElementsByTagName("algorithm").item(0).getTextContent().trim();
    if (!fnNames.contains(algo))
        throw new IllegalStateException("algorithm " + algo + " has no <function> definition");
}

Try / catch

try {
    ruleLoader.load();
} catch (ConfigException e) {
    if (e.getMessage().startsWith("can't find function of name")) {
        LOG.error("Missing <function> block in rule.xml: {}", e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: rule.xml <tableRule> whose <algorithm>foo</algorithm> has no matching <function name="foo" ...> block; also produced when the algorithm name is misspelled or case-mismatched, or when loadFunctions failed earlier so the function map is incomplete.

Common situations: Copying a tableRule from a sample but forgetting to copy its function definition; typos in the algorithm name; XML validation ordering issues where the function block was deleted during cleanup.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/ca2f5a97c012a208. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/config/loader/xml/XMLRuleLoader.java:150

				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));
			}
		}
	}

	private RuleConfig loadRule(Element element) throws SQLSyntaxErrorException {
		//读取columns
		Element columnsEle = ConfigUtil.loadElement(element, "columns");
		String column = columnsEle.getTextContent();
		String[] columns = SplitUtil.split(column, ',', true);
		if (columns.length > 1) {
			throw new ConfigException("table rule coulmns has multi values:"
					+ columnsEle.getTextContent());
		}

View on GitHub (pinned to 65f8d8beb7)