skip to content

What is SimpleAsyncUncaughtExceptionHandler and what exactly does it do out of the box?

level: middleimportance: should knowfreq 45%

answer

  1. default AsyncUncaughtExceptionHandler
  2. logs at ERROR, nothing else
  3. org.springframework.aop.interceptor
  4. void-only, replace via AsyncConfigurer
  5. returning null keeps it

basics

~10 s

It's Spring's default AsyncUncaughtExceptionHandler for void @Async methods. When such a method throws an uncaught exception, this handler just logs it at ERROR level (with the failing method) and does nothing else.

solid answer

~40 s

SimpleAsyncUncaughtExceptionHandler is the out-of-the-box implementation of AsyncUncaughtExceptionHandler that Spring uses when you don't provide your own via AsyncConfigurer. Its handleUncaughtException implementation simply logs the throwable at ERROR level, including the method that failed. That's all — no metrics, no alerting, no retry, no rethrow, and the caller stays unaware. It applies only to void-returning @Async methods; future-returning methods store their own exceptions. Because log-only is rarely enough for production fire-and-forget work, teams typically replace it with a custom handler that also records metrics, emits alerts, or writes a dead-letter entry. Knowing the default exists matters because it means void async failures are not truly silent — they appear in ERROR logs — which is often the first place to look when an async side effect mysteriously didn't happen.

go deeper

for a junior

Knows the default logs the exception.

for a middle

Can name it, its package/behavior, and how to replace it.

for a senior

Explains why log-only is inadequate and designs a richer handler.

for a principal

Standardizes async failure observability (metrics/alerts/dead-letter) org-wide rather than relying on the default.

## What it is `SimpleAsyncUncaughtExceptionHandler` (package `org.springframework.aop.interceptor`) is the **default** implementation of the `AsyncUncaughtExceptionHandler` strategy interface. Spring installs it automatically for `@EnableAsync` when you don't supply a custom handler through `AsyncConfigurer.getAsyncUncaughtExceptionHandler()`. ## What it does Exactly one thing: its `handleUncaughtException(Throwable ex, Method method, Object... params)` **logs the exception at ERROR level**, including the signature of the method that threw. It does **not**: - rethrow to the caller (impossible — different thread), - increment any metric, - send any alert, - retry, - persist anything. ## Scope It is only ever invoked for **void** `@Async` methods. Methods returning `Future`/`CompletableFuture` capture their own exceptions in the future and never touch this handler. ## Why it matters in interviews and in practice - It's the reason people say void async exceptions are "swallowed but logged" — the log line is this handler's doing. - If you replace it with a poorly written custom handler that catches and drops, you lose even that log line — now failures are truly invisible. - For production, log-only is usually insufficient: fire-and-forget tasks (emails, audit records) often need alerting or dead-lettering, so you override it. ## How to replace it Implement `AsyncConfigurer` on your `@EnableAsync @Configuration` and return a custom `AsyncUncaughtExceptionHandler` from `getAsyncUncaughtExceptionHandler()`. Returning `null` (the default) keeps `SimpleAsyncUncaughtExceptionHandler`. ## Gotcha The handler runs on the async worker thread, so its logs won't carry the original request's MDC/trace context unless you propagated it (e.g. via a `TaskDecorator`).

  • How would you know a void @Async method failed if you only have the default handler?
    Look for an ERROR-level log entry from SimpleAsyncUncaughtExceptionHandler naming the failing method and stack trace. That log line is the only default signal — there's no metric, alert, or caller notification.
  • Why is log-only often insufficient in production?
    Fire-and-forget work (emails, audit writes, cache warmups) can silently fail and no one notices until a log dive. Teams override the handler to also emit metrics, alerts, or dead-letter records for actionable failure handling.

saying these in an interview costs you the question

  • Thinking SimpleAsyncUncaughtExceptionHandler rethrows or retries
  • Believing it handles future-returning methods too
  • Assuming it swallows silently with no logging
  • Confusing it with a logging framework config rather than a Spring strategy bean

context