Skip to content

@Async event listener suspending function throws IllegalArgumentException #36214

Description

@joaodias14

Spring Framework 7.0.3
Java 17
Kotlin 2.2.21 (Coroutines 1.10.2)

While asynchronously handling an event, a suspending function throws IllegalArgumentException as follows:

java.lang.IllegalArgumentException: Invalid return type for async method (only Future and void supported): class java.lang.Object
	at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.doSubmit(AsyncExecutionAspectSupport.java:290) ~[spring-aop-7.0.3.jar:7.0.3]
	at org.springframework.aop.interceptor.AsyncExecutionInterceptor.invoke(AsyncExecutionInterceptor.java:127) ~[spring-aop-7.0.3.jar:7.0.3]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-7.0.3.jar:7.0.3]
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:719) ~[spring-aop-7.0.3.jar:7.0.3]
	at com.example.demo.EventHandler$$SpringCGLIB$$0.handleCustomEventFail(<generated>) ~[classes/:na]
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:565) ~[na:na]

The event listener function:

    @Async
    @EventListener
    suspend fun handleCustomEventFail(customSpringEvent: CustomSpringEvent) {
        println("[suspend] Handling ${customSpringEvent.id} event")
    }

A similar event listener non-suspending function works just fine:

    @Async
    @EventListener
    fun handleCustomEventSuccess(customSpringEvent: CustomSpringEvent) {
        println("[non-suspend] Handling ${customSpringEvent.id} event")
    }

A minimal reproducible example is available at https://github.com/joaodias14/demo-async.

We can workaround it by using a coroutine builder function, such as CoroutineScope.launch(), to explicitly start a coroutine, but it would be great if @Async works seamlessly with suspending functions.

Activity

  1. joaodias14 commented on Jan 26, 2026

    @joaodias14
    Author

    I am now wondering: is it redundant to use @Async on an event listener suspending function?

  2. self-assigned this
    on Jan 29, 2026
  3. added
    theme: kotlinAn issue related to Kotlin support
    and removed on Jan 29, 2026
  4. added this to the 7.0.4 milestone on Jan 29, 2026
  5. sdeleuze commented on Jan 29, 2026

    @sdeleuze
    Contributor

    It is indeed redundant for Reactive types or suspending function, so here I would advise to not use @Async. That said, we can likely refine the error message to provide better guidance, so I will refine that.

  6. added
    in: coreIssues in core modules (aop, beans, core, context, expression)
    and removed
    theme: kotlinAn issue related to Kotlin support
    on Jan 29, 2026
  7. joaodias14 commented on Jan 29, 2026

    @joaodias14
    Author

    Thanks for the feedback @sdeleuze !

  8. modified the milestones: 7.0.4, 7.0.5, 7.0.x on Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)type: enhancementA general enhancement

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions