MyCATApache/Mycat-Server · error · IllegalArgumentException

rehashNodeDir must be a directory

Error message

rehashNodeDir must be a directory

What it means

RehashLauncher.execute() validates the configured rehashNodeDir before starting the rehash workers. If the path already exists but is a regular file rather than a directory, it throws IllegalArgumentException. This is an upfront configuration sanity check so worker output files are never written into an invalid path.

Solutions

  1. Delete or rename the file at the configured rehashNodeDir path so the launcher can create a directory there.
  2. Correct the rehashNodeDir value in the rehash config to point to a directory (or a nonexistent path that can be created).
  3. Re-run the rehash launch after fixing the path.

Example fix

// before
rehashNodeDir=/opt/mycat/rehash-output.zip
// after
rehashNodeDir=/opt/mycat/rehash-output
# and on the shell:
# rm /opt/mycat/rehash-output.zip
Defensive patterns

Strategy: validation

Validate before calling

File dir = new File(args.getRehashNodeDir());
if (dir.isFile()) throw new IllegalStateException("rehashNodeDir is a file: " + dir);
if (!dir.exists() && !dir.mkdirs()) throw new IllegalStateException("cannot create " + dir);

Try / catch

try {
  RehashLauncher.launch(args);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("must be a directory")) {
    new File(args.getRehashNodeDir()).delete(); // remove offending file, then retry
  }
}

Prevention

When it happens

Trigger: Launching rehash with a rehashNodeDir property pointing at an existing file (e.g. a previously created tarball, log file, or an accidentally created plain file at that path).

Common situations: A previous failed run created rehashNodeDir as a file, the user pointed the config at a file path by typo, or the path was reused for a different artifact.

Related errors


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

Appendix: source

Thrown at src/main/java/io/mycat/util/rehasher/RehashLauncher.java:137

		dataSource.setDefaultAutoCommit(true);
		dataSource.setDefaultReadOnly(true);
		dataSource.setDriverClassName(args.getJdbcDriver());
		dataSource.setEnable(true);
		dataSource.setPassword(args.getPassword());
		dataSource.setTestOnBorrow(true);
		dataSource.setTestOnReturn(true);
		dataSource.setTestWhileIdle(true);
		dataSource.setUrl(args.getJdbcUrl());
		dataSource.setUsername(args.getUser());
	}
	
	private RehashLauncher execute() throws IOException{
		final String[] tables=args.getTables();
		final File outputDir=new File(args.getRehashNodeDir());
		if(!outputDir.exists()){
			outputDir.mkdirs();
		}else if(outputDir.isFile()){
			throw new IllegalArgumentException("rehashNodeDir must be a directory");
		}else if(outputDir.canWrite()){
			throw new IllegalArgumentException("rehashNodeDir must be writable");
		}
		latch=new CountDownLatch(tables.length);
		for(int i=0,l=tables.length;i<l;i++){
			final int tableIdx=i;
			final String table=tables[tableIdx];
			final File output=new File(outputDir,table);
			if(output.exists()){
				output.delete();
			}
			output.createNewFile();
			executor.execute(new RehashRunner(output, table));
		}
		return this;
	}
	
	private void shutdown(){

View on GitHub (pinned to 65f8d8beb7)