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.

Got the actual stack trace?

Paste it into our free AI explainer to get the cause and the fix for your specific case — no signup, nothing to install.

Explain my error

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