MyCATApache/Mycat-Server · error · IllegalArgumentException
dataNode name is null
Error message
dataNode name is null
What it means
TableConfig's constructor requires a non-null dataNode; if the dataNode parameter is null it throws IllegalArgumentException("dataNode name is null"). Every table must map to at least one data node so Mycat knows where to store and read its rows.
Solutions
- Add dataNode="<existing-dataNode>" to the <table> element in schema.xml.
- Ensure the referenced dataNode is defined before the table config is built.
Example fix
// before (schema.xml) <table name="orders" primaryKey="id" /> // after <table name="orders" primaryKey="id" dataNode="dn1" />
Defensive patterns
Strategy: validation
Validate before calling
if (dataNode == null || dataNode.isEmpty()) throw new IllegalArgumentException("dataNode required for table " + tableName); Try / catch
try { TableConfig tc = new TableConfig(...); } catch (IllegalArgumentException e) { if ("dataNode name is null".equals(e.getMessage())) { LOG.error("table {} missing dataNode", tableName); } throw e; } Prevention
- Require dataNode on every <table> element in schema.xml.
- Validate that referenced dataNodes exist in the dataNode definitions.
- Add schema.xml checks to CI so missing attributes fail before deployment.
When it happens
Trigger: Constructing TableConfig with dataNode == null, typically from a <table> element in schema.xml that has no dataNode attribute.
Common situations: Table entry in schema.xml missing dataNode="dn1"; programmatically generated config omitting the data node; XML loader returning null for an empty attribute.
Related errors
- table name is null
- invalid table dataNodes
- functionName is null
- name is null
- can not find the data node with name
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/4e28786536ff9821.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/config/model/TableConfig.java:73
private final String parentKey;
private final String locateRTableKeySql;
// only has one level of parent
private final boolean secondLevel;
private final boolean partionKeyIsPrimaryKey;
private volatile List<SQLTableElement> tableElementList;
private volatile String tableStructureSQL;
private volatile Map<String, List<String>> dataNodeTableStructureSQLMap;
private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(false);
public TableConfig(String tableName, String primaryKey, boolean autoIncrement, boolean needAddLimit, int tableType,
String dataNode, Set<String> dbType, RuleConfig rule, boolean ruleRequired,
TableConfig parentTC, boolean isChildTable, String joinKey,
String parentKey, String subTables, boolean fetchStoreNodeByJdbc) {
if (tableName == null) {
throw new IllegalArgumentException("table name is null");
} else if (dataNode == null) {
throw new IllegalArgumentException("dataNode name is null");
}
this.primaryKey = primaryKey;
this.autoIncrement = autoIncrement;
this.needAddLimit = needAddLimit;
this.fetchStoreNodeByJdbc = fetchStoreNodeByJdbc;
this.tableType = tableType;
this.dbTypes = dbType;
if (ruleRequired && rule == null) {
throw new IllegalArgumentException("ruleRequired but rule is null");
}
this.name = tableName.toUpperCase();
String theDataNodes[] = SplitUtil.split(dataNode, ',', '$', '-');
if (theDataNodes == null || theDataNodes.length <= 0) {
throw new IllegalArgumentException("invalid table dataNodes: " + dataNode);
}
dataNodes = new ArrayList<String>(theDataNodes.length);
for (String dn : theDataNodes) {View on GitHub (pinned to 65f8d8beb7)