quarkusio/quarkus · error · BlockingOperationNotAllowedException
You have attempted to perform a blocking operation on a IO t
Error message
You have attempted to perform a blocking operation on a IO thread. This is not allowed, as blocking the IO thread will cause major performance issues with your application. If you want to perform blocking StatelessSession operations make sure you are doing it from a worker thread.
What it means
Quarkus rejects blocking operations (JPA/Hibernate calls that hit the database) when they run on a Vert.x IO (event-loop) thread, because blocking would stall event-loop processing for all requests. TransactionScopedStatelessSession.checkBlocking() uses BlockingOperationControl to verify the current thread allows blocking before any StatelessSession operation. Hibernate ORM is inherently blocking, so these calls must happen on a worker thread.
Source
Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedStatelessSession.java:108
false, false);
} else {
throw new ContextNotActiveException(
"Cannot use the StatelessSession because neither a transaction nor a CDI request context is active."
+ " Consider adding @Transactional to your method to automatically activate a transaction,"
+ " or @ActivateRequestContext if you have valid reasons not to use transactions.");
}
} else {
throw new ContextNotActiveException(
"Cannot use the StatelessSession because no transaction is active."
+ " Consider adding @Transactional to your method to automatically activate a transaction,"
+ " or set '" + HibernateOrmRuntimeConfig.extensionPropertyKey("request-scoped.enabled")
+ "' to 'true' if you have valid reasons not to use transactions.");
}
}
private void checkBlocking() {
if (!BlockingOperationControl.isBlockingAllowed()) {
throw new BlockingOperationNotAllowedException(
"You have attempted to perform a blocking operation on a IO thread. This is not allowed, as blocking the IO thread will cause major performance issues with your application. If you want to perform blocking StatelessSession operations make sure you are doing it from a worker thread.");
}
}
private boolean isInTransaction() {
try {
switch (transactionManager.getStatus()) {
case Status.STATUS_ACTIVE:
case Status.STATUS_COMMITTING:
case Status.STATUS_MARKED_ROLLBACK:
case Status.STATUS_PREPARED:
case Status.STATUS_PREPARING:
return true;
default:
return false;
}
} catch (Exception e) {
throw new RuntimeException(e);View on GitHub (pinned to e1c734241f)
Solutions
- Annotate the endpoint/method with @Blocking (or remove @NonBlocking) so Quarkus dispatches it to a worker thread
- Wrap the blocking StatelessSession usage in Mutiny's Infrastructure.getCurrentVertxWorkerPool().executeBlocking or runInWorkerThread semantics (e.g. Uni.createFrom().item(() -> ...) .runSubscriptionOn(Infrastructure.getDefaultWorkerPool()))
- Use a Panache reactive or Hibernate Reactive API instead of the blocking StatelessSession if the code is reactive
- Check that no library callback (e.g. security check, filter) marked the execution as non-blocking unexpectedly
Example fix
// before
@GET
@NonBlocking
public Uni<Pet> get(long id) {
return Uni.createFrom().item(() -> {
return statelessSession.createQuery(...).uniqueResult(); // throws
});
}
// after
@GET
@Blocking
public Pet get(long id) {
return statelessSession.createQuery(...).uniqueResult();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!BlockingOperationControl.isBlockingAllowed()) {
// defer to worker thread or throw a friendly error
return runOnWorkerThread(() -> doHibernateWork());
} Type guard
boolean canRunBlockingNow() {
return BlockingOperationControl.isBlockingAllowed();
} Try / catch
try {
return statelessSession.createQuery(...).uniqueResult();
} catch (BlockingOperationNotAllowedException e) {
Log.warn("Blocking Hibernate call on IO thread; rerouting");
return Infrastructure.getDefaultWorkerPool().executeBlocking(() -> doWork()).await().indefinitely();
} Prevention
- Mark endpoints that use blocking JPA with @Blocking
- Never call Hibernate APIs inside reactive callbacks (map/chain) running on the event loop
- Prefer Hibernate Reactive or Panache reactive APIs in reactive endpoints
When it happens
Trigger: Calling any StatelessSession method (refresh, createQuery, createNamedQuery, createNativeQuery, createNamedStoredProcedureQuery, createStoredProcedureQuery, insert, update, delete, etc.) from code running on an event-loop thread — e.g. a @NonBlocking annotated endpoint, an unauthenticated blocking=never resource, reactive routes, or a Vert.x worker-less callback.
Common situations: REST endpoint that returns Uni/Multi or is marked non-blocking but still calls blocking Hibernate StatelessSession; calling session code from a reactive pipeline (map/subscribe callbacks) that stays on the IO thread; changing an endpoint from blocking to reactive without moving DB access to a worker thread.
Related errors
- You have attempted to perform a blocking operation on a IO t
- Blocking gRPC client call made from the event loop. If the c
- Methods that are annotated with JPA Listener annotations sho
- @PersistenceUnit annotations are not supported at the class
- This PersistenceProvider does not support createEntityManage
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/803aa340f21b1b81.
Report an issue: GitHub.