{"record":{"id":"b81459f219f95cda","repo":"apache/flink","slug":"the-executorservice-is-shut-down-already-no-calla","errorCode":null,"errorMessage":"The ExecutorService is shut down already. No Callables can be executed.","messagePattern":"The ExecutorService is shut down already\\. No Callables can be executed\\.","errorType":"exception","errorClass":"RejectedExecutionException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/util/concurrent/DirectExecutorService.java","lineNumber":252,"sourceCode":"        }\n\n        if (iterator.hasNext()) {\n            throw new TimeoutException(\"Could not finish execution of tasks within time.\");\n        } else {\n            throw new ExecutionException(\"No tasks finished successfully.\", exception);\n        }\n    }\n\n    @Override\n    public void execute(@Nonnull Runnable command) {\n        throwRejectedExecutionExceptionIfShutdown();\n\n        command.run();\n    }\n\n    private void throwRejectedExecutionExceptionIfShutdown() {\n        if (isShutdown() && triggerRejectedExecutionException) {\n            throw new RejectedExecutionException(\n                    \"The ExecutorService is shut down already. No Callables can be executed.\");\n        }\n    }\n\n    static class CompletedFuture<V> implements Future<V> {\n        private final V value;\n        private final Exception exception;\n\n        CompletedFuture(V value, Exception exception) {\n            this.value = value;\n            this.exception = exception;\n        }\n\n        @Override\n        public boolean cancel(boolean mayInterruptIfRunning) {\n            return false;\n        }\n","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/util/concurrent/DirectExecutorService.java#L234-L270","documentation":"DirectExecutorService can be constructed in a mode (triggerRejectedExecutionException) where any submission after shutdown() throws RejectedExecutionException with this message. This matches the standard ExecutorService contract that a shut-down executor refuses new work, letting callers detect use-after-shutdown deterministically instead of silently running the task.","triggerScenarios":"Calling execute(), submit(), invokeAll(), or invokeAny() on a DirectExecutorService after shutdown(), when the service was created with rejection-on-shutdown enabled (the default constructor enables it).","commonSituations":"Components sharing a DirectExecutorService instance that outlives a shutdown in tests or teardown; lifecycle races where a callback submits work during close(); reusing a static executor across test cases that shuts it down per test.","solutions":["Fix ordering so no submissions happen after shutdown(); cancel the producers first, then shut down.","Guard submission sites with !executor.isShutdown() when late tasks are legal and should be dropped.","Create a fresh DirectExecutorService per lifecycle scope instead of reusing one across shutdown boundaries."],"exampleFix":"// before\nexecutor.shutdown();\nexecutor.execute(task);\n\n// after\nexecutor.shutdown();\nif (!executor.isShutdown()) { executor.execute(task); } // or reorder shutdown after all submissions","handlingStrategy":"validation","validationCode":"if (!executor.isShutdown()) { executor.execute(task); }","typeGuard":null,"tryCatchPattern":"try { executor.execute(task); }\ncatch (RejectedExecutionException e) { /* executor shut down: drop or re-route the task */ }","preventionTips":["Cancel/shutdown producers before shutting down the executor.","Guard all submission sites with isShutdown() when late work is droppable.","Scope executor lifetime to the component that owns its tasks."],"tags":["concurrency","executor","shutdown","lifecycle"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}