{"record":{"id":"803aa340f21b1b81","repo":"quarkusio/quarkus","slug":"you-have-attempted-to-perform-a-blocking-operation-803aa3","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"exception","errorClass":"BlockingOperationNotAllowedException","httpStatus":null,"severity":"error","filePath":"extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedStatelessSession.java","lineNumber":108,"sourceCode":"                        false, false);\n            } else {\n                throw new ContextNotActiveException(\n                        \"Cannot use the StatelessSession because neither a transaction nor a CDI request context is active.\"\n                                + \" Consider adding @Transactional to your method to automatically activate a transaction,\"\n                                + \" or @ActivateRequestContext if you have valid reasons not to use transactions.\");\n            }\n        } else {\n            throw new ContextNotActiveException(\n                    \"Cannot use the StatelessSession because no transaction is active.\"\n                            + \" Consider adding @Transactional to your method to automatically activate a transaction,\"\n                            + \" or set '\" + HibernateOrmRuntimeConfig.extensionPropertyKey(\"request-scoped.enabled\")\n                            + \"' to 'true' if you have valid reasons not to use transactions.\");\n        }\n    }\n\n    private void checkBlocking() {\n        if (!BlockingOperationControl.isBlockingAllowed()) {\n            throw new BlockingOperationNotAllowedException(\n                    \"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.\");\n        }\n    }\n\n    private boolean isInTransaction() {\n        try {\n            switch (transactionManager.getStatus()) {\n                case Status.STATUS_ACTIVE:\n                case Status.STATUS_COMMITTING:\n                case Status.STATUS_MARKED_ROLLBACK:\n                case Status.STATUS_PREPARED:\n                case Status.STATUS_PREPARING:\n                    return true;\n                default:\n                    return false;\n            }\n        } catch (Exception e) {\n            throw new RuntimeException(e);","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedStatelessSession.java#L90-L126","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n@GET\n@NonBlocking\npublic Uni<Pet> get(long id) {\n    return Uni.createFrom().item(() -> {\n        return statelessSession.createQuery(...).uniqueResult(); // throws\n    });\n}\n// after\n@GET\n@Blocking\npublic Pet get(long id) {\n    return statelessSession.createQuery(...).uniqueResult();\n}","handlingStrategy":"try-catch","validationCode":"if (!BlockingOperationControl.isBlockingAllowed()) {\n    // defer to worker thread or throw a friendly error\n    return runOnWorkerThread(() -> doHibernateWork());\n}","typeGuard":"boolean canRunBlockingNow() {\n    return BlockingOperationControl.isBlockingAllowed();\n}","tryCatchPattern":"try {\n    return statelessSession.createQuery(...).uniqueResult();\n} catch (BlockingOperationNotAllowedException e) {\n    Log.warn(\"Blocking Hibernate call on IO thread; rerouting\");\n    return Infrastructure.getDefaultWorkerPool().executeBlocking(() -> doWork()).await().indefinitely();\n}","preventionTips":["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"],"tags":["jpa","hibernate-orm","reactive","event-loop"],"backgroundTag":"blocking-operation-on-io-thread","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}