quarkusio/quarkus · error · IllegalStateException
No current Mutiny.StatelessSession found - no reactive stat
Error message
No current Mutiny.StatelessSession found - no reactive stateless session was found in the Vert.x context and the context was not marked to open a new session lazily - a stateless session is opened automatically for JAX-RS resource methods annotated with an HTTP method (@GET, @POST, etc.); inherited annotations are not taken into account - you may need to annotate the business method with @Transactional, @WithStatelessSession or @WithStatelessTransaction
What it means
SessionOperations.getStatelessSession mirrors getSession but for Mutiny.StatelessSession: it throws IllegalStateException when the Vert.x duplicated context holds neither a reactive stateless session nor a lazily-opened stateless session marker. Stateless-session Panache operations require the context to be managed by @WithStatelessSession/@WithStatelessTransaction/@Transactional (or a stateless JAX-RS setup). It is a context-propagation failure, not a query error.
Source
Thrown at extensions/panache/hibernate-reactive-panache-common/runtime/src/main/java/io/quarkus/hibernate/reactive/panache/common/runtime/SessionOperations.java:342
Context context = vertxContext();
// First make sure we don't already have an opened managed session
Uni<Mutiny.StatelessSession> error = checkNoManagedSession(context, persistenceUnitName);
if (error != null) {
return error;
}
Optional<OpenedSessionsState.SessionWithKey<Mutiny.StatelessSession>> opened = OPENED_SESSIONS_STATE_STATELESS
.getOpenedSession(context, persistenceUnitName);
if (opened.isPresent()) {
return Uni.createFrom().item(opened.get().session());
} else if (ContextLocals.get(context, SESSION_ON_DEMAND_KEY, null) != null) {
trackOnDemandSession(context, persistenceUnitName);
return Uni.createFrom()
.item(() -> HibernateReactiveRecorder.getStatelessSession(persistenceUnitName, SESSION_ON_DEMAND_KEY));
} else if (ContextLocals.get(context, TRANSACTIONAL_METHOD_KEY, null) != null) {
return Uni.createFrom()
.item(() -> HibernateReactiveRecorder.getStatelessSession(persistenceUnitName, TRANSACTIONAL_METHOD_KEY));
} else {
throw new IllegalStateException("No current Mutiny.StatelessSession found"
+ "\n\t- no reactive stateless session was found in the Vert.x context and the context was not marked to open a new session lazily"
+ "\n\t- a stateless session is opened automatically for JAX-RS resource methods annotated with an HTTP method (@GET, @POST, etc.); inherited annotations are not taken into account"
+ "\n\t- you may need to annotate the business method with @Transactional, @WithStatelessSession or @WithStatelessTransaction");
}
}
/**
* @return the current reactive session stored in the context, or {@code null} if no session exists
*/
public static Mutiny.Session getCurrentSession(String persistenceUnitName) {
Context context = vertxContext();
return OPENED_SESSIONS_STATE.getOpenedSession(context, persistenceUnitName)
.map(OpenedSessionsState.SessionWithKey::session)
.orElse(null);
}
/**
* @return the current reactive stateless session stored in the context, or {@code null} if no stateless session existsView on GitHub (pinned to e1c734241f)
Solutions
- Annotate the business method with @WithStatelessSession or @WithStatelessTransaction so a stateless session is opened on demand.
- Use @Transactional if the operation is transactional and stateless-session backed.
- Ensure the HTTP-verb annotation is directly on the JAX-RS resource method (inherited annotations are ignored).
- Keep the work on the Vert.x duplicated context — do not hop threads with plain executors; use Mutiny emitOn with a context-preserving executor if needed.
- If you actually need a managed session, switch to @WithSession/stateful APIs instead of stateless ones.
Example fix
// before
public Uni<Product> refresh(Product p) {
return Panache.withStatelessSession(s -> s.refresh(p)); // no stateless session in context
}
// after
@WithStatelessSession
public Uni<Product> refresh(Product p) {
return Panache.withStatelessSession(s -> s.refresh(p));
} Defensive patterns
Strategy: validation
Validate before calling
if (Vertx.currentContext() == null || !statelessMarkersPresent()) {
throw new IllegalStateException("Stateless Panache calls require @WithStatelessSession/@WithStatelessTransaction on the calling method");
} Try / catch
try { return Panache.withStatelessSession(s -> s.refresh(p)); } catch (IllegalStateException e) { if (e.getMessage().startsWith("No current Mutiny.StatelessSession found")) { log.error("Missing @WithStatelessSession annotation", e); } throw e; } Prevention
- Use @WithStatelessSession/@WithStatelessTransaction (not @WithSession) for stateless APIs so the right marker is set
- Do not mix managed-session and stateless-session APIs in one call chain
- Keep stateless DB work on the Vert.x duplicated context; avoid thread hopping
- Annotate the concrete JAX-RS method with its HTTP verb (inherited annotations are ignored)
When it happens
Trigger: Calling stateless-session Panache operations (e.g. via StatelessSession-backed repositories, withStatelessSession APIs) from a context without markers: unannotated business methods, background threads losing the duplicated context, schedulers, or code relying on inherited HTTP annotations on a superclass.
Common situations: Mixing @WithSession (managed session) code paths with stateless APIs — the stateless lookup finds no stateless marker; calling stateless operations from a thread pool; forgetting @WithStatelessTransaction on an event consumer.
Related errors
- No current Mutiny.Session found - no reactive session was f
- No current Vertx context found
- Not supported yet upstream
- Stateless operations not supported
- Limiting to 0 values is not supported
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/1efa6b9006464d50.
Report an issue: GitHub.