Describe the bug
When OpenSearch fails to start — for example, because a plugin throws a RuntimeException from createComponent or any other method invoked during bootstrap — the JVM process does not exit. It hangs indefinitely after printing the startup exception stack trace.
This is especially problematic in containerized environments (Docker, Kubernetes) where a crashed process must exit with a non-zero code so the orchestrator can detect the failure and take action (restart, alert, etc.).
Steps to reproduce
- Implement a plugin that throws a
RuntimeException during createComponent (or anywhere else called during bootstrap).
- Run OpenSearch (e.g., inside Docker).
- Observe that after the exception is logged, the process does not terminate.
Expected behavior
OpenSearch exits with a non-zero status code when a fatal exception prevents startup.
Actual behavior
The process hangs. The following stack trace is logged but the process remains alive:
org.opensearch.bootstrap.StartupException: java.lang.RuntimeException: java.lang.RuntimeException: dummy
at org.opensearch.bootstrap.OpenSearch.init(OpenSearch.java:173)
at org.opensearch.bootstrap.OpenSearch.execute(OpenSearch.java:160)
at org.opensearch.common.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:110)
at org.opensearch.cli.Command.mainWithoutErrorHandling(Command.java:146)
at org.opensearch.cli.Command.main(Command.java:101)
at org.opensearch.bootstrap.OpenSearch.main(OpenSearch.java:126)
Analysis
In OpenSearch.main(String[]), the exit(status) call is only reached when main(args, opensearch, terminal) returns a non-OK status code. Non-OK codes are produced only for UserException and OptionException. StartupException — thrown by OpenSearch.init() when bootstrap fails — is not handled anywhere in the call chain and escapes main(String[]) as an unchecked exception, completely bypassing the exit(status) call.
Fix
#22259
Environment
- OpenSearch running in Docker
- Plugin throwing
RuntimeException from createComponent during bootstrap
Describe the bug
When OpenSearch fails to start — for example, because a plugin throws a
RuntimeExceptionfromcreateComponentor any other method invoked during bootstrap — the JVM process does not exit. It hangs indefinitely after printing the startup exception stack trace.This is especially problematic in containerized environments (Docker, Kubernetes) where a crashed process must exit with a non-zero code so the orchestrator can detect the failure and take action (restart, alert, etc.).
Steps to reproduce
RuntimeExceptionduringcreateComponent(or anywhere else called during bootstrap).Expected behavior
OpenSearch exits with a non-zero status code when a fatal exception prevents startup.
Actual behavior
The process hangs. The following stack trace is logged but the process remains alive:
Analysis
In
OpenSearch.main(String[]), theexit(status)call is only reached whenmain(args, opensearch, terminal)returns a non-OK status code. Non-OK codes are produced only forUserExceptionandOptionException.StartupException— thrown byOpenSearch.init()when bootstrap fails — is not handled anywhere in the call chain and escapesmain(String[])as an unchecked exception, completely bypassing theexit(status)call.Fix
#22259
Environment
RuntimeExceptionfromcreateComponentduring bootstrap