MyCATApache/Mycat-Server · error · IllegalArgumentException

invalid table dataNodes

Error message

invalid table dataNodes: ${dataNode}

What it means

After parsing the dataNode string with SplitUtil.split (which expands comma lists and $/- ranges), TableConfig requires at least one resulting node. If the split yields null or an empty array, IllegalArgumentException("invalid table dataNodes: ...") is thrown, embedding the offending raw value.

Solutions

  1. Set a valid dataNode list on the <table> element, e.g. dataNode="dn1" or dataNode="dn$0-dn$2".
  2. Fix malformed range syntax so SplitUtil can expand it to real node names.
  3. Remove empty entries/extra commas from the dataNode value.

Example fix

// before (schema.xml)
<table name="orders" dataNode="" />
// after
<table name="orders" dataNode="dn$0-dn$2" />
Defensive patterns

Strategy: validation

Validate before calling

String[] dns = SplitUtil.split(dataNode, ',', '$', '-');
if (dns == null || dns.length == 0) throw new IllegalArgumentException("empty dataNode list for table " + tableName);

Try / catch

try { new TableConfig(...); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("invalid table dataNodes")) { LOG.error("fix dataNode value: {}", e.getMessage()); } throw e; }

Prevention

When it happens

Trigger: dataNode parameter is an empty string, blank/whitespace-only value, or a malformed range expression (e.g. dn$0-dn$1 with bad numbers) so split returns nothing.

Common situations: <table dataNode=""> empty attribute in schema.xml; typo like dataNode=" , ,"; invalid range syntax such as dn$-dn$2; only whitespace between commas.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/main/java/io/mycat/config/model/TableConfig.java:88

        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) {
            dataNodes.add(dn);
        }

        if (subTables != null && !subTables.equals("")) {
            String sTables[] = SplitUtil.split(subTables, ',', '$', '-');
            if (sTables == null || sTables.length <= 0) {
                throw new IllegalArgumentException("invalid table subTables");
            }
            this.distTables = new ArrayList<String>(sTables.length);
            for (String table : sTables) {
                distTables.add(table);
            }
        } else {
            this.distTables = new ArrayList<String>();
        }

View on GitHub (pinned to 65f8d8beb7)