{"record":{"id":"38238b16bc355998","repo":"MyCATApache/Mycat-Server","slug":"rehashnodedir-must-be-writable","errorCode":null,"errorMessage":"rehashNodeDir must be writable","messagePattern":"rehashNodeDir must be writable","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/util/rehasher/RehashLauncher.java","lineNumber":139,"sourceCode":"\t\tdataSource.setDriverClassName(args.getJdbcDriver());\n\t\tdataSource.setEnable(true);\n\t\tdataSource.setPassword(args.getPassword());\n\t\tdataSource.setTestOnBorrow(true);\n\t\tdataSource.setTestOnReturn(true);\n\t\tdataSource.setTestWhileIdle(true);\n\t\tdataSource.setUrl(args.getJdbcUrl());\n\t\tdataSource.setUsername(args.getUser());\n\t}\n\t\n\tprivate RehashLauncher execute() throws IOException{\n\t\tfinal String[] tables=args.getTables();\n\t\tfinal File outputDir=new File(args.getRehashNodeDir());\n\t\tif(!outputDir.exists()){\n\t\t\toutputDir.mkdirs();\n\t\t}else if(outputDir.isFile()){\n\t\t\tthrow new IllegalArgumentException(\"rehashNodeDir must be a directory\");\n\t\t}else if(outputDir.canWrite()){\n\t\t\tthrow new IllegalArgumentException(\"rehashNodeDir must be writable\");\n\t\t}\n\t\tlatch=new CountDownLatch(tables.length);\n\t\tfor(int i=0,l=tables.length;i<l;i++){\n\t\t\tfinal int tableIdx=i;\n\t\t\tfinal String table=tables[tableIdx];\n\t\t\tfinal File output=new File(outputDir,table);\n\t\t\tif(output.exists()){\n\t\t\t\toutput.delete();\n\t\t\t}\n\t\t\toutput.createNewFile();\n\t\t\texecutor.execute(new RehashRunner(output, table));\n\t\t}\n\t\treturn this;\n\t}\n\t\n\tprivate void shutdown(){\n\t\twhile(true){\n\t\t\ttry {","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/util/rehasher/RehashLauncher.java#L121-L157","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["chmod/chown the rehashNodeDir so the user running MyCat has write permission (e.g. chmod u+w or chown mycat:mycat).","Change rehashNodeDir in the config to a writable location for the current user.","If running in a container, mount the output volume as read-write and ensure the process UID owns it."],"exampleFix":"// shell fix\n// before: dr-xr-xr-x root root /opt/mycat/rehash-node\n// after:\n// chown -R mycat:mycat /opt/mycat/rehash-node && chmod u+rwx /opt/mycat/rehash-node","handlingStrategy":"validation","validationCode":"File dir = new File(args.getRehashNodeDir());\nif (dir.isDirectory() && !dir.canWrite()) throw new IllegalStateException(\"not writable: \" + dir);","typeGuard":null,"tryCatchPattern":"try {\n  RehashLauncher.launch(args);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"must be writable\")) {\n    logger.error(\"fix permissions on {} for user {}\", args.getRehashNodeDir(), System.getProperty(\"user.name\"));\n  }\n}","preventionTips":["Run MyCat/rehash under a user that owns its output directories.","Ensure container volumes mounting the output dir are read-write.","Check directory permissions after any deployment or user change."],"tags":["configuration","filesystem","permissions","rehash"],"backgroundTag":"file-write-permission-denied","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}