elastic/elasticsearch · error · TestClustersException
Failed to set the keystore password for {}
Error message
Failed to set the keystore password for {} What it means
Thrown by startElasticsearchProcess() when Files.writeString(esInputFile, keystorePassword+'\n', CREATE) raises an IOException, wrapped as TestClustersException with the node identity. The code writes the keystore password to a temp file so it can be fed to the ES process via processBuilder.redirectInput; failing to materialise that file means the secured keystore cannot be unlocked at boot.
Source
Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java:932
processBuilder.directory(workingDir.toFile());
Map<String, String> environment = processBuilder.environment();
// Don't inherit anything from the environment for as that would lack reproducibility
environment.clear();
environment.putAll(getESEnvironment());
String cliJvmArgsString = String.join(" ", cliJvmArgs);
environment.put("CLI_JAVA_OPTS", cliJvmArgsString + " " + System.getProperty("tests.jvm.argline", ""));
// Direct the stderr to the ES log file. This should capture any jvm problems to start.
// Stdout is discarded because ES duplicates the log file to stdout when run in the foreground.
processBuilder.redirectOutput(ProcessBuilder.Redirect.appendTo(esOutputFile.toFile()));
processBuilder.redirectErrorStream(true);
if (keystorePassword != null && keystorePassword.length() > 0) {
try {
Files.writeString(esInputFile, keystorePassword + "\n", StandardOpenOption.CREATE);
processBuilder.redirectInput(esInputFile.toFile());
} catch (IOException e) {
throw new TestClustersException("Failed to set the keystore password for " + this, e);
}
}
LOGGER.info("Running `{}` in `{}` for {} env: {}", command, workingDir, this, environment);
Process esProcess;
try {
esProcess = processBuilder.start();
} catch (IOException e) {
throw new TestClustersException("Failed to start ES process for " + this, e);
}
testClustersRegistryProvider.get().storeProcess(id(), esProcess);
reaperServiceProvider.get().registerPid(toString(), esProcess.pid());
}
@Internal
public Path getDistroDir() {
return canUseSharedDistribution()
? getExtractedDistributionDir().toFile().listFiles()[0].toPath()
: workingDir.resolve("distro").resolve(getVersion() + "-" + testDistribution);View on GitHub (pinned to db6a809a66)
Solutions
- Read the cause IOException for the precise FS error (message vs permission vs space).
- Clean build/testclusters/<node> so esInputFile and its parent are recreated.
- Free disk / inodes and fix ownership on the build dir.
- Shorten the build path on Windows to avoid MAX_PATH for the input file.
Defensive patterns
Strategy: try-catch
Validate before calling
// Confirm the esInputFile parent is writable before start
Path inputParent = node.getEsInputFile().getParent();
if (Files.exists(inputParent) && !Files.isWritable(inputParent)) {
throw new IllegalStateException("esInputFile dir not writable: " + inputParent);
}
if (node.getKeystorePassword() != null && node.getKeystorePassword().length() > 0
&& OS.current() == OS.WINDOWS && node.getEsInputFile().toString().length() > 240) {
throw new IllegalStateException("esInputFile path too long for Windows: " + node.getEsInputFile());
} Try / catch
try {
node.start();
} catch (TestClustersException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Failed to set the keystore password")) {
throw new IllegalStateException("Keystore password file write failed (disk/perms/path): "
+ e.getCause(), e);
}
throw e;
} Prevention
- Keep build/testclusters paths short, especially on Windows.
- Maintain consistent ownership of build/ across runs.
- Free disk before secured-cluster test runs.
When it happens
Trigger: A non-empty keystorePassword is configured, and writing it to esInputFile fails: parent dir missing/ read-only, disk full, permission residue, path-too-long, or antivirus interference. The check fires at process launch time inside start().
Common situations: Disk full on CI agent. Permission residue from a root-owned prior run. Windows MAX_PATH in the esInputFile path. Antivirus locking temp files. Stale build/testclusters after a host change.
Related errors
- Failed to create working directory for {}, with: {}
- supplied keystore file {} does not exist, require for {}
- Can't append roles file {} to {}
- CONFIG
- the ${keystoreType} keystore [${path}]does not contain a pri
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/264c9d12a9e7755f.
Report an issue: GitHub.