elastic/elasticsearch · error · UserException

74

74

Error message

File [{}] does not exist

What it means

Thrown by `add-file` after the keystore is loaded, when the file path given for a setting does not exist on disk (`Files.exists(file) == false`). It is an IO_ERROR (74) — the path is syntactically accepted but the filesystem lookup fails. The file bytes are read with `Files.readAllBytes`, so the path must point to a readable file.

Source

Thrown at distribution/tools/keystore-cli/src/main/java/org/elasticsearch/cli/keystore/AddFileKeyStoreCommand.java:71

        if (argumentValues.size() % 2 != 0) {
            throw new UserException(ExitCodes.USAGE, "settings and filenames must come in pairs");
        }

        final KeyStoreWrapper keyStore = getKeyStore();

        for (int i = 0; i < argumentValues.size(); i += 2) {
            final String setting = argumentValues.get(i);

            if (keyStore.getSettingNames().contains(setting) && options.has(forceOption) == false) {
                if (terminal.promptYesNo("Setting " + setting + " already exists. Overwrite?", false) == false) {
                    terminal.println("Exiting without modifying keystore.");
                    return;
                }
            }

            final Path file = getPath(argumentValues.get(i + 1));
            if (Files.exists(file) == false) {
                throw new UserException(ExitCodes.IO_ERROR, "File [" + file.toString() + "] does not exist");
            }

            keyStore.setFile(setting, Files.readAllBytes(file));
        }

        keyStore.save(env.configDir(), getKeyStorePassword().getChars());
    }

    @SuppressForbidden(reason = "file arg for cli")
    private static Path getPath(String file) {
        return PathUtils.get(file);
    }

}

View on GitHub (pinned to db6a809a66)

Solutions

  1. Verify the file exists from the same user and working directory the CLI runs under: `ls -l <path>` and `readlink -f <path>`.
  2. Use an absolute path for the file argument.
  3. Ensure the file is mounted/accessible in the same filesystem namespace (e.g., same Docker container) as the keystore process.
  4. Check the path does not contain unexpanded shell variables or `~`.

Example fix

// before
bin/elasticsearch-keystore add-file xpack.security.transport.ssl.key ssl.key
// after
bin/elasticsearch-keystore add-file xpack.security.transport.ssl.key /etc/elasticsearch/certs/node.key
Defensive patterns

Strategy: validation

Validate before calling

import java.nio.file.Files;
import java.nio.file.Path;

for (Path p : paths) {
    if (!Files.exists(p) || !Files.isRegularFile(p)) {
        throw new IllegalArgumentException("Missing or non-regular file: " + p);
    }
    if (!Files.isReadable(p)) {
        throw new IllegalArgumentException("Not readable: " + p);
    }
}

Try / catch

try {
    runAddFile(setting, path);
} catch (UserException e) {
    if (e.exitCode == ExitCodes.IO_ERROR && e.getMessage().contains("does not exist")) {
        // pre-validate path, then retry once with absolute resolved path
    } else throw e;
}

Prevention

When it happens

Trigger: Passing a relative path that does not resolve against the CLI's working directory; a typo or stale path after files moved; permissions/ownership making the path invisible to the running user; NFS mount not yet attached.

Common situations: Storing SSL keys or certificates where the absolute path differs between nodes; containers where the file is not mounted into the keystore tool's filesystem namespace; Ansible tasks referencing a path on the controller rather than the target host.

Related errors


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