MyCATApache/Mycat-Server · error · IllegalArgumentException

Invalid DataSource

Error message

Invalid DataSource:${activedIndex}

What it means

In PhysicalDBNode.getConnection, when the dataHost's balance/switch configuration yields no recognized branch (neither the write host nor a matching read-source selection), Mycat falls into the else branch and throws IllegalArgumentException("Invalid DataSource:" + activedIndex). It signals that the pool's active datasource index does not correspond to any configured source — the active index is out of sync with the actual dataSources array.

Solutions

  1. Check schema.xml dataHost writeHost/readHost configuration and fix missing or invalid host entries.
  2. Restart/reload Mycat so the DBPool's activedIndex is re-initialized to a valid source.
  3. Guard with a bounds check on activedIndex before dispatching, and fall back to the write host.
  4. Enable heartbeat logs to see why the pool switched to an invalid index; adjust switchType/heartbeat settings.

Example fix

// before
throw new IllegalArgumentException("Invalid DataSource:" + dbPool.getActivedIndex());
// after
int idx = dbPool.getActivedIndex();
PhysicalDatasource[] sources = dbPool.getSources();
if (idx < 0 || idx >= sources.length || sources[idx] == null) {
    LOGGER.warn("invalid activedIndex " + idx + ", falling back to write source");
    dbPool.getSource().getConnection(schema, autoCommit, handler, attachment);
    return;
}
throw new IllegalArgumentException("Invalid DataSource:" + idx);
Defensive patterns

Strategy: fallback

Validate before calling

int idx = dbPool.getActivedIndex();
if (idx < 0 || idx >= dbPool.getSources().length || dbPool.getSources()[idx] == null) {
    throw new IllegalStateException("activedIndex " + idx + " is not a configured datasource");
}

Type guard

boolean hasValidActiveSource(PhysicalDBPool pool) {
    int i = pool.getActivedIndex();
    return i >= 0 && i < pool.getSources().length && pool.getSources()[i] != null;
}

Try / catch

try {
    node.getConnection(schema, autoCommit, handler, attachment);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Invalid DataSource")) {
        LOGGER.warn("invalid active index, retrying on write host");
        node.getDbPool().getSource().getConnection(schema, autoCommit, handler, attachment);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling getConnection (from execute or heartbeat run) when dbPool.getActivedIndex() points at a source that is not among the pool's configured datasources — typically after a failed switch/heartbeat advanced activedIndex beyond the sources array, or with an empty/misconfigured dataHost.

Common situations: schema.xml dataHost with missing or invalid writeHost entries; a switchType failover set activedIndex to an index with no corresponding host; a config reload leaving the pool's active index stale.

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/4fbfbde0a145dec8. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/backend/datasource/PhysicalDBNode.java:146

					writeSource.getConnection(schema, autoCommit,
							handler, attachment);
					rrs.setCanRunInReadDB(false);
				}
			}else{	// 没有  /*db_type=master/slave*/ 注解,按照原来的处理方式
				LOGGER.debug("rrs.getRunOnSlave() " + rrs.getRunOnSlaveDebugInfo());	// null
				if (rrs.canRunnINReadDB(autoCommit)) {
					dbPool.getRWBanlanceCon(schema,autoCommit, handler, attachment, this.database);
				} else {
					PhysicalDatasource writeSource =dbPool.getSource();
					//记录写节点写负载值
					writeSource.setWriteCount();
					writeSource.getConnection(schema, autoCommit,
							handler, attachment);
				}
			}
		
		} else {
			throw new IllegalArgumentException("Invalid DataSource:" + dbPool.getActivedIndex());
			}
		}

//	public void getConnection(String schema,boolean autoCommit, RouteResultsetNode rrs,
//			ResponseHandler handler, Object attachment) throws Exception {
//		checkRequest(schema);
//		if (dbPool.isInitSuccess()) {
//			if (rrs.canRunnINReadDB(autoCommit)) {
//				dbPool.getRWBanlanceCon(schema,autoCommit, handler, attachment,
//						this.database);
//			} else {
//				dbPool.getSource().getConnection(schema,autoCommit, handler, attachment);
//			}
//
//		} else {
//			throw new IllegalArgumentException("Invalid DataSource:"
//					+ dbPool.getActivedIndex());
//		}

View on GitHub (pinned to 65f8d8beb7)