MyCATApache/Mycat-Server · error · ConfigException
tablesFile.properties read fail!
Error message
tablesFile.properties read fail!
What it means
ConfigComparer loads tablesFile.properties from the classpath during data migration setup. If the resource stream is null or Properties.load() throws for any reason, it wraps the failure in a ConfigException with this generic message. It signals the migration tool cannot read its table list configuration.
Solutions
- Verify tablesFile.properties exists on the classpath at the expected resource path (same package/location as TABLES_FILE constant).
- If it was null due to a missing resource, restore the file or pass the correct classpath (-cp) when launching the migrator.
- Validate the properties file syntax: no invalid \u escapes, proper key=value lines.
- Run with the working directory/classpath matching where the file lives, or place it in src/main/resources so it is packaged.
Example fix
// before (file missing on classpath) java -cp mycat.jar io.mycat.util.dataMigrator.DataMigrator ... // after java -cp mycat.jar:conf io.mycat.util.dataMigrator.DataMigrator ... # conf/ contains tablesFile.properties
Defensive patterns
Strategy: validation
Validate before calling
String res = "/tablesFile.properties";
if (ConfigComparer.class.getResource(res) == null) {
throw new IllegalStateException("tablesFile.properties not found on classpath: " + res);
}
Properties pro = new Properties();
try (InputStream in = ConfigComparer.class.getResourceAsStream(res)) {
pro.load(in); // surfaces exact parse errors
} Type guard
boolean tablesFileReadable() {
try (InputStream in = ConfigComparer.class.getResourceAsStream("/tablesFile.properties")) {
return in != null;
} catch (IOException e) { return false; }
} Try / catch
try {
loadMigrationConfig();
} catch (ConfigException e) {
if (e.getMessage().contains("tablesFile.properties read fail")) {
// verify classpath contains conf/, restore file, then retry
}
throw e;
} Prevention
- Keep tablesFile.properties in src/main/resources so it is packaged with the jar
- Always launch the migrator with the conf directory on the classpath
- Lint the properties file for invalid \u escapes before running migration
- Version-control the migrator config files to avoid accidental deletion
When it happens
Trigger: Calling the MyCat data migration tool (DataMigrator) when tablesFile.properties is missing from the classpath, is not readable, has malformed content (e.g. stray backslashes or invalid escapes causing IllegalArgumentException), or the classloader returns null for getResourceAsStream(TABLES_FILE).
Common situations: Running the migration utility from a jar/classpath that omits the properties file; file renamed or moved after edits; properties file contains a malformed unicode escape (e.g. \uxxxx) that makes Properties.load throw.
Understand the failure class
Background: "Config file not found": what it means and how to fix it in docker-sync, Maven, Vagrant, Turborepo and other tools — this error's family across 60 libraries.
Related errors
- please check file "dnindex.properties
- oldSchema: is not exists!
- newSchema: is not exists!
- new & old table config is not equal!
- please check tableFile.properties,make sure
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/1c26343062178362.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/util/dataMigrator/ConfigComparer.java:109
newDataHosts = newLoader.getDataHosts();
newDataNodes = newLoader.getDataNodes();
newSchemas = newLoader.getSchemas();
}catch(Exception e){
throw new ConfigException(" new config for migrate read fail!please check newSchema.xml or newRule.xml "+e);
}
}
private void loadTablesFile() throws Exception{
Properties pro = new Properties();
if(!isAwaysUseMaster){
dnIndexProps = loadDnIndexProps();
}
try{
pro.load(ConfigComparer.class.getResourceAsStream(TABLES_FILE));
}catch(Exception e){
throw new ConfigException("tablesFile.properties read fail!");
}
Iterator<Entry<Object, Object>> it = pro.entrySet().iterator();
while(it.hasNext()){
Entry<Object, Object> entry = it.next();
String schemaName = entry.getKey().toString();
String tables = entry.getValue().toString();
loadMigratorTables(schemaName,getTables(tables));
}
}
private String[] getTables(String tables){
if(tables.equalsIgnoreCase("all") || tables.isEmpty()){
return new String[]{};
}else{
return tables.split(",");
}
}
View on GitHub (pinned to 65f8d8beb7)