elastic/elasticsearch · error · IllegalStateException

Error processing reserved state settings file

Error message

Error processing reserved state settings file

What it means

Thrown by FileSettingsClusterSecretsLoader.readClusterSecrets() when parsing the file-based settings file (the auto-conf/reserved state settings) throws an IOException. The file exists but could not be opened or JSON-parsed, wrapped in an IllegalStateException.

Source

Thrown at distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/FileSettingsClusterSecretsLoader.java:93

     *             "file_secrets": {
     *                 "secure.setting.key.three": "Y2Nj"
     *             }
     *         }
     *     }
     * }
     * </pre>
     */
    private static SecureClusterStateSettings readClusterSecrets(Path settingsFile) {
        if (Files.exists(settingsFile) == false) {
            return SecureClusterStateSettings.EMPTY;
        }
        try (
            var bis = new BufferedInputStream(Files.newInputStream(settingsFile));
            var parser = JSON.xContent().createParser(XContentParserConfiguration.EMPTY, bis)
        ) {
            return requireNonNullElse(createFileSettingsParser().apply(parser, null), SecureClusterStateSettings.EMPTY);
        } catch (IOException e) {
            throw new IllegalStateException("Error processing reserved state settings file", e);
        }
    }

    // one-off parser used to load initial cluster secrets
    private static ConstructingObjectParser<SecureClusterStateSettings, Void> createFileSettingsParser() {
        var stateParser = new ConstructingObjectParser<SecureClusterStateSettings, Void>(
            "state",
            true,
            a -> (SecureClusterStateSettings) a[0]
        );
        stateParser.declareObject(
            optionalConstructorArg(),
            (p, c) -> SecureClusterStateSettings.fromXContent(p),
            new ParseField(ClusterSecrets.NAME)
        );

        var parser = new ConstructingObjectParser<SecureClusterStateSettings, Void>(
            "file_settings",

View on GitHub (pinned to db6a809a66)

Solutions

  1. Check the caused-by IOException for the specific I/O reason.
  2. Validate the file is valid JSON: cat <path> | python -m json.tool (or jq).
  3. Fix permissions so the ES user can read it: chmod/chown appropriately.
  4. Ensure the path is a regular file, not a directory.
Defensive patterns

Strategy: try-catch

Validate before calling

Path f = settingsFile;
if (Files.exists(f) && (Files.isDirectory(f) || !Files.isReadable(f))) {
    throw new IllegalStateException("Settings file unreadable or is a directory: " + f);
}

Try / catch

try (var bis = new BufferedInputStream(Files.newInputStream(settingsFile));
     var parser = JSON.xContent().createParser(XContentParserConfiguration.EMPTY, bis)) {
    return parser.map();
} catch (IOException e) {
    throw new IllegalStateException("Cannot parse settings file " + settingsFile, e);
}

Prevention

When it happens

Trigger: Files.newInputStream or the XContent parser throws IOException on the settings file — e.g. the file is a directory, has wrong permissions, or contains malformed JSON.

Common situations: settings.json (or the resolved file-settings path) is syntactically broken; truncated due to a concurrent write; permissions deny read to the ES user; the path points to a directory.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/168357453f3bcf0d. Report an issue: GitHub.