Home โบ Java exceptions โบ ExecutionException
ExecutionException: causes and fixes
A task run through an executor failed; the real exception is the cause.
What it looks like
java.util.concurrent.ExecutionException: java.lang.IllegalStateException: boomExtends Exception in java.util.concurrent.
What it means
When you call Future.get() and the task threw an exception, Java wraps it in ExecutionException so you can tell a failed task from your own thread being interrupted. The actual problem is in getCause(). In logs it appears as the first Caused by line, so debugging means reading the cause, not the wrapper. CompletableFuture has an equivalent, CompletionException, thrown by join().
Common causes
- Any unchecked exception inside a
CallableorRunnablesubmitted to an executor. - A checked exception declared by the Callable.
- A failed stage in a CompletableFuture chain.
- An Error such as OutOfMemoryError inside the task.
How to fix it
- Catch ExecutionException and inspect or rethrow
e.getCause(). - Log the cause with its stack trace, not only the wrapper message.
- Use
exceptionallyorhandleon CompletableFutures to recover. - Unwrap and rethrow the real exception type when your method signature allows it.
Broken and fixed
try { future.get(); }
catch (ExecutionException e) { log.error("failed"); } // cause losttry { future.get(); }
catch (ExecutionException e) {
log.error("task failed", e.getCause());
throw new RuntimeException(e.getCause());
}๐ Unravel the failing code ๐ Unravel the fix
In Spring and enterprise code
Async methods in Spring (@Async returning Future) surface failures this way; void ones go to the AsyncUncaughtExceptionHandler.
Debug it faster
Paste the whole stack trace into the stack trace beautifier to hide framework frames, jump to the root cause and find the first line of your own code. It runs in your browser, so the trace never leaves your machine.
Frequently asked questions
Is ExecutionException a checked or unchecked exception?
ExecutionException is a checked exception (it extends Exception), so the compiler forces you to catch it or declare it with throws.
Which package is ExecutionException in?
It lives in java.util.concurrent, so the import is import java.util.concurrent.ExecutionException;.
What is the first thing to check when I see ExecutionException?
Read the message and the first stack trace line in your own code. The usual causes are: Any unchecked exception inside a Callable or Runnable submitted to an executor; and A checked exception declared by the Callable.