MyCATApache/Mycat-Server · error · ConfigException
dataNode define error ,attribute can't be empty
Error message
dataNode ${dnNamePre} define error ,attribute can't be empty What it means
Thrown by XMLSchemaLoader when parsing a <dataNode> element whose required attributes (name, database, or dataHost) are missing or empty. Each dataNode must identify a name, a physical database, and a dataHost to be usable.
Solutions
- Add non-empty name, database, and dataHost attributes to the offending <dataNode> element in schema.xml
- Validate the XML against the expected dataNode structure before startup
- Check for template placeholders that were never substituted
Example fix
// before (schema.xml) <dataNode name="dn1" database="" dataHost="localhost1" /> // after <dataNode name="dn1" dataHost="localhost1" database="db1" />
Defensive patterns
Strategy: validation
Validate before calling
// ensure dataNode elements have all required attributes
for (Element dn : dataNodeElements("schema.xml")) {
for (String attr : new String[]{"name", "database", "dataHost"}) {
if (dn.getAttribute(attr).trim().isEmpty())
throw new IllegalStateException("<dataNode> missing attribute: " + attr);
}
} Try / catch
try {
configLoader.load();
} catch (ConfigException e) {
if (e.getMessage().contains("define error ,attribute can't be empty")) {
String name = extractBetween(e.getMessage(), "dataNode ", " define error");
log.error("<dataNode name='" + name + "'> is missing name/database/dataHost", e);
}
throw e;
} Prevention
- Use a checklist (name, database, dataHost) when authoring <dataNode> entries
- Validate generated XML against a schema before shipping; catch unfilled template placeholders
- Review dataNode blocks as whole units to avoid partial edits
When it happens
Trigger: A <dataNode database="db1" dataHost="host1" /> without name, or name present but database/dataHost attribute empty, in schema.xml.
Common situations: Hand-edited or generated schema.xml dropping an attribute; XML templates with unfilled placeholders (name=""); copy-paste errors creating incomplete dataNode entries.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- dataNode ' ' is not found!
- dataNode define error ,dnNames.length must…
- dataNode duplicated!
- invalid param ,connection request db is
- dataHost not exists
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/0f267205519dc25a.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/config/loader/xml/XMLSchemaLoader.java:623
String.valueOf(tableConf.getRule().getRuleAlgorithm().getPartitionNum()),
String.valueOf(tableConf.getDataNodes().size())
});
break;
}
}
private void loadDataNodes(Element root) {
//读取DataNode分支
NodeList list = root.getElementsByTagName("dataNode");
for (int i = 0, n = list.getLength(); i < n; i++) {
Element element = (Element) list.item(i);
String dnNamePre = element.getAttribute("name");
String databaseStr = element.getAttribute("database");
String host = element.getAttribute("dataHost");
//字符串不为空
if (empty(dnNamePre) || empty(databaseStr) || empty(host)) {
throw new ConfigException("dataNode " + dnNamePre + " define error ,attribute can't be empty");
}
//dnNames(name),databases(database),hostStrings(dataHost)都可以配置多个,以',', '$', '-'区分,但是需要保证database的个数*dataHost的个数=name的个数
//多个dataHost与多个database如果写在一个标签,则每个dataHost拥有所有database
//例如:<dataNode name="dn1$0-75" dataHost="localhost$1-10" database="db$0-759" />
//则为:localhost1拥有dn1$0-75,localhost2也拥有dn1$0-75(对应db$76-151)
String[] dnNames = io.mycat.util.SplitUtil.split(dnNamePre, ',', '$', '-');
String[] databases = io.mycat.util.SplitUtil.split(databaseStr, ',', '$', '-');
String[] hostStrings = io.mycat.util.SplitUtil.split(host, ',', '$', '-');
if (dnNames.length > 1 && dnNames.length != databases.length * hostStrings.length) {
throw new ConfigException("dataNode " + dnNamePre
+ " define error ,dnNames.length must be=databases.length*hostStrings.length");
}
if (dnNames.length > 1) {
List<String[]> mhdList = mergerHostDatabase(hostStrings, databases);
for (int k = 0; k < dnNames.length; k++) {
String[] hd = mhdList.get(k);View on GitHub (pinned to 65f8d8beb7)