ExecutionException

java.util.concurrent.ExecutionException: java.lang.RuntimeException: Task failed

Quick Answer

A task submitted to an executor threw an exception. The real cause is wrapped inside the ExecutionException. Call getCause() to find it.

Why This Happens

When a Callable or Runnable submitted to an ExecutorService throws an exception, it is wrapped in an ExecutionException and re-thrown when you call Future.get(). The actual exception is available via getCause(). Always unwrap to find the real error.

The Problem

Future<String> future = executor.submit(() -> {
    throw new RuntimeException("DB connection failed");
});
try {
    future.get();
} catch (ExecutionException e) {
    System.out.println(e.getMessage()); // Unhelpful wrapped message
}

The Fix

Future<String> future = executor.submit(() -> {
    throw new RuntimeException("DB connection failed");
});
try {
    future.get();
} catch (ExecutionException e) {
    Throwable cause = e.getCause(); // Unwrap the real exception
    System.err.println("Task failed: " + cause.getMessage());
    cause.printStackTrace();
}

Step-by-Step Fix

  1. 1

    Identify the ExecutionException

    Find the Future.get() call that throws ExecutionException.

  2. 2

    Unwrap the cause

    Call getCause() to get the actual exception that the task threw.

  3. 3

    Fix the underlying error

    Debug and fix the root cause exception, not the ExecutionException wrapper.

Bugsly catches this automatically

Bugsly's AI analyzes this error pattern in real-time, explains what went wrong in plain English, and suggests the exact fix — before your users even report it.

Try Bugsly free