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
- Annotate the calling method with @WithSession (or @WithTransaction) so a reactive session is opened for the context
- Add @Transactional to the method if transactional semantics are desired
- For JAX-RS resources, annotate the endpoint method directly with @GET/@POST/etc. so the session opens automatically
- 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
- Never access Mutiny.Session from code paths without a session-opening annotation in the same Vert.x context
- For schedulers/startup code, always add @WithSession (or @WithTransaction)
- Prefer annotating the business method rather than relying on ambient REST handling
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
- Value not set for ${param}
- Attempting to boot a blocking Hibernate ORM instance on a re
- No Vert.x instance has been registered in ArC ?
- When using offline mode with `quarkus.hibernate-orm.database
- Mutiny.SessionFactory bean not found
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/925e6df16754d415.
Report an issue: GitHub.