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.

Solutions

  1. Fix the 'rulesFile' property to an absolute path pointing to an existing regular file
  2. Verify with 'ls -l <path>' that the file exists and is not a directory (or a dangling symlink)
  3. If running in Docker, mount the file as a volume and use the in-container path
  4. 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

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


AI-assisted analysis of languagetool-org/languagetool@2e990059ce (2026-09-06). Data as JSON: /api/errors/415ab6d772a85f77. Report an issue: GitHub.

Appendix: 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)