languagetool-org/languagetool · error · RuntimeException
Rules Configuration file cannot be found:
Error message
Rules Configuration file cannot be found:
What it means
The 'rulesFile' server property points to a rules configuration file that customizes rule behavior. If the path given does not exist on disk or is not a regular file (e.g. a directory), the server config constructor throws this RuntimeException because it cannot apply the requested rules configuration.
Source
Thrown at languagetool-server/src/main/java/org/languagetool/server/HTTPServerConfig.java:384
// default value 0 = use maxCheckThreads setting (for compatibility)
maxTextCheckerThreads = Integer.parseInt(getOptionalProperty(props, "maxTextCheckerThreads", "0"));
if (maxTextCheckerThreads < 0) {
throw new IllegalArgumentException("Invalid value for maxTextCheckerThreads, must be >= 1: " + maxTextCheckerThreads);
}
textCheckerQueueSize = Integer.parseInt(getOptionalProperty(props, "textCheckerQueueSize", "8"));
if (textCheckerQueueSize < 0) {
throw new IllegalArgumentException("Invalid value for textCheckerQueueSize, must be >= 1: " + textCheckerQueueSize);
}
boolean atdMode = getOptionalProperty(props, "mode", "LanguageTool").equalsIgnoreCase("AfterTheDeadline");
if (atdMode) {
throw new IllegalArgumentException("The AfterTheDeadline mode is not supported anymore in LanguageTool 3.8 or later");
}
String rulesConfigFilePath = getOptionalProperty(props, "rulesFile", null);
if (rulesConfigFilePath != null) {
rulesConfigFile = new File(rulesConfigFilePath);
if (!rulesConfigFile.exists() || !rulesConfigFile.isFile()) {
throw new RuntimeException("Rules Configuration file cannot be found: " + rulesConfigFile);
}
}
String remoteRulesConfigFilePath = getOptionalProperty(props, "remoteRulesFile", null);
if (remoteRulesConfigFilePath != null) {
remoteRulesConfigFile = new File(remoteRulesConfigFilePath);
if (!remoteRulesConfigFile.exists() || !remoteRulesConfigFile.isFile()) {
throw new RuntimeException("Remote rules configuration file cannot be found: " + remoteRulesConfigFile);
}
}
cacheSize = Integer.parseInt(getOptionalProperty(props, "cacheSize", "0"));
if (cacheSize < 0) {
throw new IllegalArgumentException("Invalid value for cacheSize: " + cacheSize + ", use 0 to deactivate cache");
}
if (props.containsKey("cacheTTLSeconds") && !props.containsKey("cacheSize")) {
throw new IllegalArgumentException("Use of cacheTTLSeconds without also setting cacheSize has no effect.");
}
cacheTTLSeconds = Integer.parseInt(getOptionalProperty(props, "cacheTTLSeconds", "300"));
maxErrorsPerWordRate = Float.parseFloat(getOptionalProperty(props, "maxErrorsPerWordRate", "0"));View on GitHub (pinned to 2e990059ce)
Solutions
- Fix the 'rulesFile' property to an absolute path pointing to an existing regular file
- Verify with 'ls -l <path>' that the file exists and is not a directory (or a dangling symlink)
- If running in Docker, mount the file as a volume and use the in-container path
- If no custom rules config is needed, remove the 'rulesFile' property entirely
Example fix
// before (server.properties) rulesFile=./config/rule-config.txt // after (server.properties) rulesFile=/opt/languagetool/config/rule-config.txt
Defensive patterns
Strategy: validation
Validate before calling
String p = props.getProperty("rulesFile");
if (p != null) {
File f = new File(p);
if (!f.exists() || !f.isFile()) throw new IllegalStateException("rulesFile missing or not a file: " + p);
} Try / catch
try {
serverConfig = new HTTPServerConfig(props);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Rules Configuration file cannot be found")) {
log.error("Fix the rulesFile path: {}", e.getMessage());
}
throw e;
} Prevention
- Use absolute paths in server.properties
- Mount config files into containers explicitly and verify with a startup existence check
- Deploy the rules file before starting the server (provisioning order)
When it happens
Trigger: Starting the HTTP server with 'rulesFile=/path/to/file' where the path does not exist, is a directory, or the server's working directory/container differs from where the file was placed.
Common situations: Relative path in server.properties resolved against a different working directory when started via systemd/Docker; file deleted or renamed; typo in path; Docker volume not mounted.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Remote rules configuration file cannot be found:
- beolingusFile not found:
- ngramLangIdentData does not exist or is a directory (needs t
- The AfterTheDeadline mode is not supported anymore in Langua
- Invalid value for cacheSize: , use 0 to deactivate cache
AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06).
Data as JSON: /api/errors/415ab6d772a85f77.
Report an issue: GitHub.