apache/flink · error · ExecutionException
No tasks finished successfully.
Error message
No tasks finished successfully.
What it means
DirectExecutorService.invokeAny executes callables one by one on the calling thread and returns the first success. If every callable throws, it wraps the LAST observed exception in an ExecutionException with this message. This mirrors the standard ExecutorService.invokeAny contract for the all-failed case.
Source
Thrown at flink-core/src/main/java/org/apache/flink/util/concurrent/DirectExecutorService.java:211
@Override
@Nonnull
public <T> T invokeAny(@Nonnull Collection<? extends Callable<T>> tasks)
throws ExecutionException {
throwRejectedExecutionExceptionIfShutdown();
Exception exception = null;
for (Callable<T> task : tasks) {
try {
return task.call();
} catch (Exception e) {
// try next task
exception = e;
}
}
throw new ExecutionException("No tasks finished successfully.", exception);
}
@Override
public <T> T invokeAny(
@Nonnull Collection<? extends Callable<T>> tasks, long timeout, @Nonnull TimeUnit unit)
throws ExecutionException, TimeoutException {
throwRejectedExecutionExceptionIfShutdown();
long end = System.currentTimeMillis() + unit.toMillis(timeout);
Exception exception = null;
Iterator<? extends Callable<T>> iterator = tasks.iterator();
while (end > System.currentTimeMillis() && iterator.hasNext()) {
Callable<T> callable = iterator.next();
try {
return callable.call();View on GitHub (pinned to 2f3c205e92)
Solutions
- Inspect getCause() of the ExecutionException — it is the last task's exception, which is usually the most informative starting point.
- Fix or make reachable at least one of the underlying resources/callables.
- If you need all failure causes, replace invokeAny with per-task submit and collect exceptions yourself.
Example fix
// before
try { service.invokeAny(tasks); } catch (ExecutionException e) { log.error("failed"); }
// after
try { service.invokeAny(tasks); }
catch (ExecutionException e) { log.error("all tasks failed, last cause:", e.getCause()); } Defensive patterns
Strategy: try-catch
Try / catch
try { T r = executor.invokeAny(tasks); }
catch (ExecutionException e) { Throwable root = e.getCause(); /* handle last task's failure */ } Prevention
- Remember invokeAny surfaces only the LAST failure cause.
- Ensure at least one callable is expected to succeed; otherwise use submit+collect.
- Log getCause(), not the wrapper, when diagnosing.
When it happens
Trigger: Calling invokeAny(tasks) where tasks is non-empty and every Callable.call() throws; the returned exception's cause is the final task's exception, earlier ones are lost.
Common situations: Failover/retry helpers that try a list of replicas or strategies with the direct executor; unit tests simulating all-backends-down; missing the fact that only the last cause is preserved when debugging.
Related errors
- Could not finish execution of tasks within time.
- Task has been cancelled.
- The ExecutorService is shut down already. No Callables can b
- Error while getting the file registered under '${name}' from
- Concurrent access to KryoSerializer. Thread 1: {threadName1}
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/95926d8e808d4036.
Report an issue: GitHub.