MyCATApache/Mycat-Server · error · IllegalArgumentException

rehashNodeDir must be writable

Error message

rehashNodeDir must be writable

What it means

RehashLauncher.execute() checks that the configured rehashNodeDir is writable when it already exists as a directory. If File.canWrite() returns false, it throws IllegalArgumentException, because worker threads could not write the per-table output files into it.

Solutions

  1. chmod/chown the rehashNodeDir so the user running MyCat has write permission (e.g. chmod u+w or chown mycat:mycat).
  2. Change rehashNodeDir in the config to a writable location for the current user.
  3. If running in a container, mount the output volume as read-write and ensure the process UID owns it.

Example fix

// shell fix
// before: dr-xr-xr-x root root /opt/mycat/rehash-node
// after:
// chown -R mycat:mycat /opt/mycat/rehash-node && chmod u+rwx /opt/mycat/rehash-node
Defensive patterns

Strategy: validation

Validate before calling

File dir = new File(args.getRehashNodeDir());
if (dir.isDirectory() && !dir.canWrite()) throw new IllegalStateException("not writable: " + dir);

Try / catch

try {
  RehashLauncher.launch(args);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("must be writable")) {
    logger.error("fix permissions on {} for user {}", args.getRehashNodeDir(), System.getProperty("user.name"));
  }
}

Prevention

When it happens

Trigger: Launching rehash with rehashNodeDir set to an existing directory the current OS user cannot write to (owned by another user, read-only mount, root-owned directory).

Common situations: Running MyCat as a non-root user while the output dir was created by root, running in a container with a read-only volume, or directory permissions like 0755 owned by another account.

Understand the failure class

Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.

Related errors


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

Appendix: source

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

		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(){
		while(true){
			try {

View on GitHub (pinned to 65f8d8beb7)