quarkusio/quarkus · error · IllegalStateException

No current Mutiny.Session found - you need to annotate your

Error message

No current Mutiny.Session found
	- you need to annotate your method with @Transactional to open a reactive session
	- alternatively, you can use @WithSessionOnDemand, @WithSession, or @WithTransaction
	- for JAX-RS resources, annotate the method directly with an HTTP method (@GET, @POST, etc.) to automatically open a session

What it means

Hibernate Reactive requires a session bound to the current Vert.x/Duplicate context. Quarkus opens one lazily only when an interceptor (e.g. @Transactional, @WithSession) has marked the context as session-enabled. If getSession is called with no such context marker, this IllegalStateException explains the annotations/HTTP-method markers that enable session creation.

Source

Thrown at extensions/hibernate-reactive/runtime/src/main/java/io/quarkus/hibernate/reactive/runtime/HibernateReactiveRecorder.java:142

                };
            }
        };
    }

    public static Mutiny.Session getSession(String persistenceUnitName) {
        return getSession(persistenceUnitName, TRANSACTIONAL_METHOD_KEY);
    }

    public static Mutiny.Session getSession(String persistenceUnitName, String contextKey) {
        Context context = Vertx.currentContext();

        Optional<OpenedSessionsState.SessionWithKey<Mutiny.Session>> openedSession = OPENED_SESSIONS_STATE.getOpenedSession(
                context,
                persistenceUnitName);
        if (openedSession.isPresent()) {
            return openedSession.get().session();
        } else if (ContextLocals.get(contextKey).isEmpty()) {
            throw new IllegalStateException(noSessionFoundErrorMessage());
        } else {
            // Store the persistence unit name so that we can close only this session at the end of the interceptor
            ContextLocals.put(PERSISTENCE_UNIT_NAME_KEY, persistenceUnitName);
            LOG.debugf("Opening lazy session for Persistence Unit '%s'", persistenceUnitName);
            return OPENED_SESSIONS_STATE.createNewSession(persistenceUnitName, context);
        }
    }

    public Function<SyntheticCreationalContext<Mutiny.StatelessSession>, Mutiny.StatelessSession> statelessSessionSupplier(
            String persistenceUnitName) {
        return new Function<SyntheticCreationalContext<Mutiny.StatelessSession>, Mutiny.StatelessSession>() {

            @Override
            public Mutiny.StatelessSession apply(SyntheticCreationalContext<Mutiny.StatelessSession> context) {
                return new MutinyStatelessSessionDelegator() {
                    @Override
                    public Mutiny.StatelessSession delegate() {
                        return getStatelessSession(persistenceUnitName);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Annotate the calling method with @WithSession (or @WithTransaction) so a reactive session is opened for the context
  2. Add @Transactional to the method if transactional semantics are desired
  3. For JAX-RS resources, annotate the endpoint method directly with @GET/@POST/etc. so the session opens automatically
  4. If using @WithSessionOnDemand, ensure the session is accessed through the intended lazy provider path

Example fix

// before
public Uni<List<Fruit>> list() {
  return sessionProvider.getSession()...
}
// after
@WithSession
public Uni<List<Fruit>> list() {
  return sessionProvider.getSession()...
}
Defensive patterns

Strategy: validation

Validate before calling

import io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession;
import io.smallrye.mutiny.Uni;

// Ensure the method that touches the session carries an opening annotation:
// @WithSession / @WithTransaction / @Transactional on the calling method,
// or an HTTP method annotation (@GET, @POST...) on the JAX-RS resource method.

Try / catch

try {
    return doQuery();
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("No current Mutiny.Session found")) {
        throw new IllegalStateException("Add @WithSession or @Transactional to the calling method (or annotate the REST method with @GET/@POST)", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling a Mutiny.Session-producing API (e.g. via SessionMethodProvider / HibernateReactiveRecorder.getSession) from code running on a Vert.x context that was never marked by a session-opening interceptor — i.e. neither @Transactional, @WithSession, @WithSessionOnDemand, @WithTransaction, nor an annotated JAX-RS HTTP method is active on the call path.

Common situations: Calling repository/DAO methods from a startup event, scheduler, or non-annotated REST method; invoking session code inside @Scheduled or a plain CDI observer without @WithSession; forgetting @Transactional on a service method invoked outside a REST resource.

Related errors


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