{"record":{"id":"149531294da37a6c","repo":"apache/flink","slug":"task-has-been-cancelled","errorCode":null,"errorMessage":"Task has been cancelled.","messagePattern":"Task has been cancelled\\.","errorType":"exception","errorClass":"CancellationException","httpStatus":null,"severity":"warning","filePath":"flink-core/src/main/java/org/apache/flink/util/concurrent/DirectExecutorService.java","lineNumber":181,"sourceCode":"                    new Future<T>() {\n                        @Override\n                        public boolean cancel(boolean mayInterruptIfRunning) {\n                            return false;\n                        }\n\n                        @Override\n                        public boolean isCancelled() {\n                            return true;\n                        }\n\n                        @Override\n                        public boolean isDone() {\n                            return false;\n                        }\n\n                        @Override\n                        public T get() {\n                            throw new CancellationException(\"Task has been cancelled.\");\n                        }\n\n                        @Override\n                        public T get(long timeout, @Nonnull TimeUnit unit) {\n                            throw new CancellationException(\"Task has been cancelled.\");\n                        }\n                    });\n        }\n\n        return result;\n    }\n\n    @Override\n    @Nonnull\n    public <T> T invokeAny(@Nonnull Collection<? extends Callable<T>> tasks)\n            throws ExecutionException {\n        throwRejectedExecutionExceptionIfShutdown();\n","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/util/concurrent/DirectExecutorService.java#L163-L199","documentation":"DirectExecutorService runs tasks on the caller thread; when a Future returned by its submit-family methods is cancelled before execution, it hands back a Future whose get() throws CancellationException with this message. The future reports isCancelled()==true and isDone()==false, so any blocking get() is required to fail per the java.util.concurrent contract.","triggerScenarios":"Calling future.get() on a Future obtained from DirectExecutorService (e.g. via submit then cancel, or the completed/cancelled future wrappers) after cancellation.","commonSituations":"Test code using DirectExecutorService to simulate async behavior then asserting on cancelled futures; cancellation of probes/tasks in components that run with the direct executor during shutdown; generic code that blocks on futures without checking isCancelled().","solutions":["Check future.isCancelled() before calling get().","Catch CancellationException where cancellation is an expected outcome and handle it as control flow, not an error.","Avoid cancelling tasks whose results you still intend to consume."],"exampleFix":"// before\nT result = future.get();\n\n// after\nif (future.isCancelled()) {\n    return; // task was cancelled; nothing to retrieve\n}\nT result = future.get();","handlingStrategy":"try-catch","validationCode":"if (future.isCancelled()) { /* skip get() */ }","typeGuard":null,"tryCatchPattern":"try { T v = future.get(); }\ncatch (CancellationException e) { /* cancelled: normal control flow, abort dependent work */ }","preventionTips":["Check isCancelled() before every get().","Treat CancellationException as expected in cancellable pipelines, never log it as ERROR.","Do not consume results of futures you may cancel."],"tags":["concurrency","executor","future","cancellation"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}