quarkusio/quarkus · error · UnsupportedOperationException
shutdownNow not allowed on managed executor service
Error message
shutdownNow not allowed on managed executor service
What it means
Same lifecycle restriction as shutdown(): DelegatingExecutorService.shutdownNow() throws UnsupportedOperationException because the wrapped executor is Quarkus-managed and must not be forcibly terminated by application code. Additionally note shutdownNow's return value (pending tasks) can never be provided for a managed pool.
Source
Thrown at extensions/virtual-threads/runtime/src/main/java/io/quarkus/virtual/threads/DelegatingExecutorService.java:43
// container managed executors are never shut down from the application's perspective
return false;
}
public boolean isTerminated() {
// container managed executors are never shut down from the application's perspective
return false;
}
public boolean awaitTermination(final long timeout, final TimeUnit unit) {
return false;
}
public void shutdown() {
throw new UnsupportedOperationException("shutdown not allowed on managed executor service");
}
public List<Runnable> shutdownNow() {
throw new UnsupportedOperationException("shutdownNow not allowed on managed executor service");
}
public String toString() {
return delegate.toString();
}
}
View on GitHub (pinned to e1c734241f)
Solutions
- Drop the shutdownNow() call; let Quarkus manage executor termination
- Use an application-created executor for components that need to force shutdown
- Use a completion flag/Future.cancel(true) per task instead of shutting down the whole pool
Example fix
// before List<Runnable> pending = executor.shutdownNow(); // after future.cancel(true); // cancel individual tasks instead
Defensive patterns
Strategy: validation
Validate before calling
if (isQuarkusManaged(executor)) { /* never call shutdownNow */ } Type guard
boolean isManagedExecutor(ExecutorService es) { return es.getClass().getName().startsWith("io.quarkus.virtual.threads"); } Try / catch
try { executor.shutdownNow(); } catch (UnsupportedOperationException ignored) { /* managed by Quarkus */ } Prevention
- Cancel individual tasks via Future.cancel instead of pool shutdown
- Own the executor lifecycle yourself when you need shutdownNow semantics
- Review third-party components for implicit executor shutdown
When it happens
Trigger: Calling shutdownNow() on the injected managed/virtual-thread executor service, typically during app shutdown or task cancellation logic.
Common situations: Code that cancels in-flight work at shutdown; third-party libraries that call shutdownNow() on an ExecutorService handed to them.
Related errors
- shutdown not allowed on managed executor service
- Trying to invoke ContextPropagation on a partially-configure
- This executor is managed by the container and cannot be shut
- Can only sync state on the server side of remote dev mode
- All parameters have already been loaded, it is too late to c
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/1c05a36a1fc2c2b1.
Report an issue: GitHub.