elastic/elasticsearch · error · UserException
ret
ret
Error message
Failed ${action} '${serviceId}' service What it means
Thrown by ProcrunCommand.execute when the underlying procrun executable returns a non-zero exit code. The UserException carries that exit code (`ret`) so the CLI exits with the same value procrun used. The message is templated by getFailureMessage(serviceId) and typically says something like `Failed installing service 'elasticsearch-service-x64'`. This is a passthrough of procrun's own failure, not a Java-level error.
Source
Thrown at distribution/tools/windows-service-cli/src/main/java/org/elasticsearch/windows/service/ProcrunCommand.java:84
}
String serviceId = getServiceId(options, processInfo.envVars());
preExecute(terminal, processInfo, serviceId);
List<String> procrunCmd = new ArrayList<>();
procrunCmd.add(quote(procrun.toString()));
procrunCmd.add("//%s/%s".formatted(cmd, serviceId));
if (includeLogArgs()) {
procrunCmd.add(getLogArgs(serviceId, processInfo.workingDir(), processInfo.envVars()));
}
procrunCmd.add(getAdditionalArgs(serviceId, processInfo));
ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/C", String.join(" ", procrunCmd).trim());
logger.debug((Supplier<?>) () -> "Running procrun: " + String.join(" ", processBuilder.command()));
processBuilder.inheritIO();
Process process = startProcess(processBuilder);
int ret = process.waitFor();
if (ret != ExitCodes.OK) {
throw new UserException(ret, getFailureMessage(serviceId));
} else {
terminal.println(getSuccessMessage(serviceId));
}
}
/** Quotes the given String. */
static String quote(String s) {
return '"' + s + '"';
}
/** Determines the service id for the Elasticsearch service that should be used */
private static String getServiceId(OptionSet options, Map<String, String> env) throws UserException {
List<?> args = options.nonOptionArguments();
if (args.size() > 1) {
throw new UserException(ExitCodes.USAGE, "too many arguments, expected one service id");
}
final String serviceId;
if (args.size() > 0) {View on GitHub (pinned to db6a809a66)
Solutions
- Run the command from an Administrator shell.
- For install failures, check if the service already exists: `sc query <serviceId>` and remove it first with the `remove` subcommand.
- Read the procrun log files (default in logs/) for the underlying Windows error code.
- Confirm the service id matches across install/manage/remove invocations.
Example fix
REM before (service already registered) bin\elasticsearch-service.bat install REM after bin\elasticsearch-service.bat remove bin\elasticsearch-service.bat install
Defensive patterns
Strategy: try-catch
Validate before calling
// Before invoking, check whether the service is in the expected state for the action:
// e.g. for 'install', assert the service is absent:
Process p = new ProcessBuilder("sc", "query", serviceId).redirectErrorStream(true).start();
if (p.waitFor() == 0) {
throw new IllegalStateException("Service " + serviceId + " already exists; remove it first.");
} Type guard
static boolean serviceIsRegistered(String serviceId) throws IOException, InterruptedException {
Process p = new ProcessBuilder("sc", "query", serviceId).start();
return p.waitFor() == 0;
} Try / catch
try {
procrunCmd.execute(...);
} catch (UserException e) {
// e.exitCode mirrors procrun's exit code; surface the procrun logs/
log.error("procrun {} failed for service {} (exit {}); see logs/", cmd, serviceId, e.exitCode, e);
throw e;
} Prevention
- Run service install/remove/start/stop from an elevated (Administrator) shell.
- Always pair install/remove with a specific service id; avoid re-installing over an existing registration.
- Capture procrun log output (logs/) for post-mortem.
When it happens
Trigger: Installing a service that already exists. Removing or stopping a service that is not installed/running. Running without the Administrator privileges procrun requires for service operations. Supplying a service id that collides with an existing service.
Common situations: Re-running `install` after a previous failed uninstall left the service registered. Non-admin shell. Service name conflicts with another product.
Related errors
- Missing procrun exe: ${procrun}
- USAGE
- Failed to list entitlement jars in: ${dir}
- Elasticsearch died while starting up, exit code: ${exitCode}
- CONFIG
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/e927d61e4eb2fee3.
Report an issue: GitHub.