quarkusio/quarkus · error · IllegalStateException

Suspendable @Blocking methods are not supported yet: %s.%s

Error message

Suspendable @Blocking methods are not supported yet: %s.%s

What it means

KotlinCoroutineIntegrationProcessor scans REST endpoint methods at build time. A Kotlin suspend fun annotated with @Blocking cannot be supported by the coroutine integration, so the deployment fails fast with IllegalStateException. Combining suspension with blocking execution semantics is inherently contradictory in this framework.

Source

Thrown at extensions/resteasy-reactive/rest-kotlin/deployment/src/main/java/io/quarkus/resteasy/reactive/kotlin/deployment/KotlinCoroutineIntegrationProcessor.java:92

                                    recorder));
                    if (methodContext.containsKey(EndpointIndexer.METHOD_CONTEXT_CUSTOM_RETURN_TYPE_KEY)) {
                        Type methodReturnType = (Type) methodContext.get(EndpointIndexer.METHOD_CONTEXT_CUSTOM_RETURN_TYPE_KEY);
                        if (methodReturnType != null) {
                            if (methodReturnType.name().equals(FLOW)) {
                                return List.of(processor, flowCustomizer());
                            }
                        }
                    }
                    return Collections.singletonList(processor);
                }
                return Collections.emptyList();
            }

            private void ensureNotBlocking(MethodInfo method) {
                if (method.annotation(BLOCKING_ANNOTATION) != null) {
                    String format = String.format("Suspendable @Blocking methods are not supported yet: %s.%s",
                            method.declaringClass().name(), method.name());
                    throw new IllegalStateException(format);
                }
            }

            @Override
            public ParameterExtractor handleCustomParameter(Type paramType, Map<DotName, AnnotationInstance> annotations,
                    boolean field, Map<String, Object> methodContext) {
                //look for methods that take a Continuation, these are suspendable and need to be handled differently
                if (paramType.name().equals(CONTINUATION)) {
                    methodContext.put(NAME, true);
                    if (paramType.kind() == Type.Kind.PARAMETERIZED_TYPE) {
                        Type firstGenericType = paramType.asParameterizedType().arguments().get(0);
                        if (firstGenericType.kind() == Type.Kind.WILDCARD_TYPE) {
                            methodContext.put(EndpointIndexer.METHOD_CONTEXT_CUSTOM_RETURN_TYPE_KEY,
                                    firstGenericType.asWildcardType().superBound());
                        }

                    }
                    return new NullParamExtractor();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove the @Blocking annotation from the suspend method — suspend methods are dispatched on the coroutine dispatcher automatically
  2. If blocking work is required, move it into a non-suspend method annotated with @Blocking and call it via Dispatchers.IO or a separate bean
  3. Restructure the endpoint as a non-suspend method returning CompletionStage/Uni if coroutine support is not needed

Example fix

// before
@Blocking
@GET
suspend fun list(): List<Item> = repo.findAll()
// after
@GET
suspend fun list(): List<Item> = withContext(Dispatchers.IO) { repo.findAll() }
Defensive patterns

Strategy: validation

Validate before calling

// Build-time / code-review guard
if (method.isSuspend && method.hasAnnotation(Blocking::class)) {
    error("@Blocking is not allowed on suspend functions")
}

Type guard

fun MethodInfo.isSuspendAndBlocking(): Boolean =
    this.annotation(BLOCKING_ANNOTATION) != null && parameters.any { it.name() == null } == false // check suspend flag in Jandex

Prevention

When it happens

Trigger: Declaring a JAX-RS resource method in Kotlin as `suspend fun` and annotating it with io.smallrye.common.annotation.Blocking.

Common situations: Developers assuming they need @Blocking because the coroutine runs on a worker thread, or copy-pasting @Blocking annotations from Java endpoints onto suspend functions.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/0ddb37bf3fdbcc3f. Report an issue: GitHub.