apache/flink · warning · CancellationException
Task has been cancelled.
Error message
Task has been cancelled.
What it means
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.
Source
Thrown at flink-core/src/main/java/org/apache/flink/util/concurrent/DirectExecutorService.java:181
new Future<T>() {
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return false;
}
@Override
public boolean isCancelled() {
return true;
}
@Override
public boolean isDone() {
return false;
}
@Override
public T get() {
throw new CancellationException("Task has been cancelled.");
}
@Override
public T get(long timeout, @Nonnull TimeUnit unit) {
throw new CancellationException("Task has been cancelled.");
}
});
}
return result;
}
@Override
@Nonnull
public <T> T invokeAny(@Nonnull Collection<? extends Callable<T>> tasks)
throws ExecutionException {
throwRejectedExecutionExceptionIfShutdown();
View on GitHub (pinned to 2f3c205e92)
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.
Example fix
// before
T result = future.get();
// after
if (future.isCancelled()) {
return; // task was cancelled; nothing to retrieve
}
T result = future.get(); Defensive patterns
Strategy: try-catch
Validate before calling
if (future.isCancelled()) { /* skip get() */ } Try / catch
try { T v = future.get(); }
catch (CancellationException e) { /* cancelled: normal control flow, abort dependent work */ } Prevention
- 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.
When it happens
Trigger: Calling future.get() on a Future obtained from DirectExecutorService (e.g. via submit then cancel, or the completed/cancelled future wrappers) after cancellation.
Common situations: 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().
Related errors
- No tasks finished successfully.
- Could not finish execution of tasks within time.
- The ExecutorService is shut down already. No Callables can b
- Interrupted while uploading object for key: {}
- interrupted while acquiring lock
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/149531294da37a6c.
Report an issue: GitHub.