languagetool-org/languagetool · error · IOException

Could not load remote rules configuration at <configFile.get

Error message

Could not load remote rules configuration at <configFile.getAbsolutePath()>

What it means

The same activateRemoteRules(File) flow wraps ExecutionException from loading the remote-rule configuration as an IOException 'Could not load remote rules configuration at <path>'. Unlike [27] this comes from the ExecutionException branch, i.e. the asynchronous loading task failed while resolving/fetching the configuration.

Source

Thrown at languagetool-core/src/main/java/org/languagetool/JLanguageTool.java:647

      if (transformed != original) {
        rules.set(i, transformed);
      }
    }
  }

  public void activateRemoteRules(@Nullable File configFile) throws IOException {
    List<RemoteRuleConfig> configs;
    try {
      if (configFile != null) {
        configs = RemoteRuleConfig.load(configFile);
      } else {
        configs = Collections.emptyList();
      }
      activateRemoteRules(configs);
    } catch (IOException e) {
      throw new IOException("Could not load remote rules.", e);
    } catch (ExecutionException e) {
      throw new IOException("Could not load remote rules configuration at " + configFile.getAbsolutePath(), e);
    }
  }

  public void activateRemoteRules(List<RemoteRuleConfig> configs) throws IOException {
    // Apply A/B test filtering first - can affect which rules get enabled and thus disabled because of fallback settings
    List<String> activeAbTestsForUser = userConfig.getAbTest();
    List<RemoteRuleConfig> selectedConfigsByUserSettings = configs.stream()
      .filter(config -> {
        if (!userConfig.isPremium() && config.isPremium()) {
          return false;
        }
        String excludeABTest = config.getOptions().get("excludeABTest");
        if (excludeABTest != null && activeAbTestsForUser != null &&
          activeAbTestsForUser.stream().anyMatch(flag -> flag.matches(excludeABTest))) {
          return false;
        }
        String activeRemoteRuleAbTest = config.getOptions().get("abtest");
        if (activeRemoteRuleAbTest != null && !activeRemoteRuleAbTest.trim().isEmpty()) {

View on GitHub (pinned to 2e990059ce)

Solutions

  1. Unwrap the ExecutionException cause to see the loader's real failure.
  2. Verify network reachability of the remote rule endpoint from the host.
  3. Check credentials/keys inside the remote-rule configuration file are valid and current.
  4. Add a fallback that runs without remote rules, or retry the activation on transient network errors.

Example fix

// before
lt.activateRemoteRules(new File("remote-rules.conf")); // throws on network failure
// after
try {
  lt.activateRemoteRules(new File("remote-rules.conf"));
} catch (IOException e) {
  logger.warn("Remote rules unavailable, continuing with local rules", e);
}
Defensive patterns

Strategy: fallback

Validate before calling

// preflight the remote endpoint referenced by the config before activation
HttpResponse<String> r = client.send(req, HttpResponse.BodyHandlers.ofString());
if (r.statusCode() != 200) throw new IllegalStateException("remote rule endpoint unhealthy");

Try / catch

try {
  lt.activateRemoteRules(configFile);
} catch (IOException e) {
  logger.warn("Remote rules unavailable (" + e.getCause() + "); using local rules only");
  // continue degraded
}

Prevention

When it happens

Trigger: Calling activateRemoteRules(File) when the underlying config-loading future fails (ExecutionException): unreachable remote-rule endpoint, invalid credentials in the config, or any exception thrown inside the loader task.

Common situations: Remote rule server down or misconfigured URL in the config; network/firewall blocking the fetch in production; expired API credentials for third-party (e.g. AI) rule backends invoked via testThirdPartyAI paths.

Related errors


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