apache/shardingsphere · critical · IllegalStateException
Backend executor engine is unavailable in `%s` lifecycle sta
Error message
Backend executor engine is unavailable in `%s` lifecycle state.
What it means
IllegalStateException thrown by BackendExecutorContext.getExecutorEngine() when the executor engine field is still null and the context lifecycle state is CLOSED. After shutdown() sets lifecycleState = CLOSED, any request-side lookup of the executor engine is rejected until an explicit re-initialization; this branch is the pre-init CLOSED check (line 68). It signals the proxy backend is being used after it was shut down.
Source
Thrown at proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/context/BackendExecutorContext.java:68
* It may explicitly restore the context from the closed state for repeated proxy lifecycles in the same JVM.</p>
*/
public synchronized void init() {
closeExecutorEngine();
executorEngine = ExecutorEngine.createExecutorEngineWithSize(
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getProps().<Integer>getValue(ConfigurationPropertyKey.KERNEL_EXECUTOR_SIZE));
lifecycleState = LifecycleState.RUNNING;
}
/**
* Get executor engine.
*
* @return executor engine
* @throws IllegalStateException backend executor is unavailable in current lifecycle state
*/
public synchronized ExecutorEngine getExecutorEngine() {
if (null == executorEngine) {
if (LifecycleState.CLOSED == lifecycleState) {
throw new IllegalStateException(String.format("Backend executor engine is unavailable in `%s` lifecycle state.", lifecycleState));
}
init();
}
if (LifecycleState.RUNNING != lifecycleState) {
throw new IllegalStateException(String.format("Backend executor engine is unavailable in `%s` lifecycle state.", lifecycleState));
}
return executorEngine;
}
/**
* Shutdown backend executor context.
*
* <p>After shutdown, request-side executor lookup is rejected until the next explicit lifecycle initialization.</p>
*/
public synchronized void shutdown() {
closeExecutorEngine();
lifecycleState = LifecycleState.CLOSED;
}View on GitHub (pinned to e952770a21)
Solutions
- Ensure no query/execution path runs after ProxyContext/BackendExecutorContext shutdown; drain in-flight requests before shutting down
- If the proxy is intentionally restarted in-process, call the lifecycle init path again before issuing queries (getExecutorEngine re-inits only when state is not CLOSED)
- In tests, reset or re-initialize BackendExecutorContext between test cases instead of using it after shutdown()
Example fix
// before BackendExecutorContext.getInstance().shutdown(); ExecutorEngine engine = BackendExecutorContext.getInstance().getExecutorEngine(); // IllegalStateException // after BackendExecutorContext.getInstance().shutdown(); // restart lifecycle before next use BackendExecutorContext.getInstance().init(); ExecutorEngine engine = BackendExecutorContext.getInstance().getExecutorEngine();
Defensive patterns
Strategy: validation
Try / catch
try {
ExecutorEngine engine = BackendExecutorContext.getInstance().getExecutorEngine();
} catch (final IllegalStateException ex) {
// context is CLOSED: do not retry; re-init lifecycle or fail the request fast
throw new ServiceUnavailableException("Proxy executor is shut down", ex);
} Prevention
- Gate request handling on the proxy lifecycle (reject traffic during shutdown) so queries never race shutdown()
- In tests, re-initialize BackendExecutorContext in @BeforeEach after any shutdown() in @AfterEach
- Never cache ExecutorEngine references across restarts of the embedded proxy
When it happens
Trigger: Calling BackendExecutorContext.getInstance().getExecutorEngine() after BackendExecutorContext.shutdown() has run (proxy graceful shutdown, XA/dist transaction driver reload, or a test that shuts down the context then issues a query). The null executorEngine + LifecycleState.CLOSED combination hits the first throw.
Common situations: Shutdown hooks racing in-flight queries during proxy stop/restart; unit tests that call shutdown() in @AfterEach but reuse the singleton context afterwards; embedded proxy restarted inside the same JVM without re-running init().
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/e413289d0dbfc742.
Report an issue: GitHub.