quarkusio/quarkus · error · IllegalStateException

Quarkus already running

Error message

Quarkus already running

What it means

ApplicationLifecycleManager.run() guards against a second concurrent Quarkus application in the same JVM: it tracks currentApplication and a shutdownRequested flag. If a current application exists and shutdown has not been requested, running another application instance throws this IllegalStateException. Quarkus historically supports one application per JVM.

Source

Thrown at core/runtime/src/main/java/io/quarkus/runtime/ApplicationLifecycleManager.java:118

    public static void run(Application application, String... args) {
        run(application, null, null, args);
    }

    public static void run(Application application, Class<? extends QuarkusApplication> quarkusApplication,
            BiConsumer<Integer, Throwable> exitCodeHandler, String... args) {
        boolean alreadyStarted;
        stateLock.lock();
        try {
            //in tests, we might pass this method an already started application
            //in this case we don't shut it down at the end
            alreadyStarted = application.isStarted();
            alreadyStartedCallback.accept(alreadyStarted);
            if (shutdownHookThread == null) {
                registerHooks(exitCodeHandler == null ? defaultExitCodeHandler : exitCodeHandler);
            }
            if (currentApplication != null && !shutdownRequested) {
                throw new IllegalStateException("Quarkus already running");
            }
            exitCode = -1;
            exitThrowable = null;
            shutdownRequested = false;
            currentApplication = application;
        } finally {
            stateLock.unlock();
        }
        try {

            application.start(args);
            // now we are started, we either run the main application or just wait to exit
            // when we are in AppCDS generation we can't call the bean container, we just want to fall through to the exit
            if (quarkusApplication != null && !isAppCDSGeneration()) {
                BeanManager beanManager = CDI.current().getBeanManager();
                Set<Bean<?>> beans = beanManager.getBeans(quarkusApplication, Any.Literal.INSTANCE);
                Bean<?> bean = null;
                for (Bean<?> i : beans) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Shut down the existing application before starting a new one: Quarkus.asyncExit() or app.stop() / ApplicationLifecycleManager shutdown path so shutdownRequested is set.
  2. In tests, use @QuarkusTest lifecycle or ensure @AfterEach/@AfterAll stops the previous instance.
  3. Run each Quarkus application in a separate JVM/process if multiple instances are genuinely needed.
  4. Check for leaked instances from earlier failures and clear them via proper shutdown hooks (registerHooks is skipped only if a hook thread already exists).

Example fix

// before
Quarkus.run(MyApp.class);
Quarkus.run(MyApp.class); // IllegalStateException: Quarkus already running
// after
Quarkus.run(MyApp.class);
Quarkus.asyncExit();
Quarkus.waitForExit();
Quarkus.run(MyApp.class);
Defensive patterns

Strategy: try-catch

Validate before calling

// before starting, ensure no live instance
if (Quarkus.isStarted()) { // or your own tracking of a prior run
    throw new IllegalStateException("A Quarkus application is already running in this JVM");
}

Try / catch

try {
    Quarkus.run(App.class, args);
} catch (IllegalStateException e) {
    if ("Quarkus already running".equals(e.getMessage())) {
        Quarkus.asyncExit();
        Quarkus.waitForExit();
        Quarkus.run(App.class, args);
    } else throw e;
}

Prevention

When it happens

Trigger: Calling Quarkus.run / ApplicationLifecycleManager.run while another Quarkus application instance is still live in the same JVM and its shutdown was never requested.

Common situations: Tests that start Quarkus manually (Quarkus.run) in multiple test methods without shutting down; embedding Quarkus in an application server that boots a second instance; leaked application from a failed previous run that never called stop.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/ba55a76329842747. Report an issue: GitHub.