elastic/elasticsearch · error · UserException
USAGE
USAGE
Error message
too many arguments, expected one service id
What it means
Thrown by ProcrunCommand.getServiceId when more than one non-option argument is passed on the command line. The Windows service commands accept at most one positional argument, interpreted as the service id; anything beyond that is ambiguous and rejected with exit code USAGE. The check fires before the service id is resolved, so it does not depend on whether SERVICE_ID env var is set.
Source
Thrown at distribution/tools/windows-service-cli/src/main/java/org/elasticsearch/windows/service/ProcrunCommand.java:99
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) {
serviceId = args.get(0).toString();
} else {
serviceId = env.getOrDefault("SERVICE_ID", "elasticsearch-service-x64");
}
return serviceId;
}
/** Determines the logging arguments that should be passed to the procrun command */
private static String getLogArgs(String serviceId, Path esHome, Map<String, String> env) {
String logArgs = env.get("LOG_OPTS");
if (logArgs != null && logArgs.isBlank() == false) {
return logArgs;
}
String logsDir = env.get("SERVICE_LOG_DIR");
if (logsDir == null || logsDir.isBlank()) {View on GitHub (pinned to db6a809a66)
Solutions
- Pass at most one positional argument (the service id), or none to use the SERVICE_ID env var / default.
- Quote any value containing spaces: `elasticsearch-service.bat install "my service"`.
- Run `elasticsearch-service.bat help` to confirm the expected argument shape.
Example fix
REM before bin\elasticsearch-service.bat install es-9 es-prod REM after set SERVICE_ID=es-9 bin\elasticsearch-service.bat install
Defensive patterns
Strategy: validation
Validate before calling
List<String> positional = options.nonOptionArguments().stream().map(String::valueOf).toList();
if (positional.size() > 1) {
throw new IllegalArgumentException("Expected at most one service id; got " + positional);
} Type guard
static boolean atMostOnePositional(List<?> args) {
return args != null && args.size() <= 1;
} Try / catch
try {
String sid = ProcrunCommand.getServiceId(options, env);
} catch (UserException e) {
if (e.exitCode == ExitCodes.USAGE && e.getMessage().contains("too many arguments")) {
// re-print help and exit
} else throw e;
} Prevention
- Quote any service id containing spaces.
- Prefer setting SERVICE_ID env var over passing it positionally in scripts.
- Print usage on argument parse errors in wrappers around the bat file.
When it happens
Trigger: Running `elasticsearch-service.bat install foo bar` (two positional args). Passing extra flags without their leading dash so they are parsed as positional. Copy-paste errors adding a stray token.
Common situations: Operators assume the command takes a service name plus an action. Misuse of quoting that splits a single value into two tokens.
Related errors
- Missing procrun exe: ${procrun}
- ret
- USAGE
- USAGE
- Elasticsearch died while starting up, exit code: ${exitCode}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/d9d3c38fcd76b98a.
Report an issue: GitHub.