quarkusio/quarkus · error · RollbackException
Transaction was already rolled back (e.g., by the transactio
Error message
Transaction was already rolled back (e.g., by the transaction reaper)
What it means
At the end of a @Transactional method, endTransaction commits/rolls back the transaction, but first it verifies a transaction still exists on the thread. If tm.getTransaction() returns null, the transaction vanished — typically because the Narayana transaction reaper aborted it after the timeout — and this RollbackException is thrown. It signals your transaction exceeded its timeout and work was rolled back behind your back.
Source
Thrown at extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/interceptor/TransactionalInterceptorBase.java:453
tx.setRollbackOnly();
}
} catch (IllegalStateException e) {
log.warn("Cannot set rollback-only, transaction already ended", e);
}
}
protected void handleException(InvocationContext ic, Throwable t, Transaction tx) throws Exception {
handleExceptionNoThrow(ic, t, tx);
sneakyThrow(t);
}
protected void endTransaction(TransactionManager tm, Transaction tx, RunnableWithException afterEndTransaction)
throws Exception {
try {
Transaction current = tm.getTransaction();
if (current == null) {
throw new RollbackException("Transaction was already rolled back (e.g., by the transaction reaper)");
}
if (tx != current) {
throw new RuntimeException(jtaLogger.i18NLogger.get_wrong_tx_on_thread());
}
if (tx.getStatus() == Status.STATUS_MARKED_ROLLBACK) {
tm.rollback();
} else {
tm.commit();
}
} finally {
afterEndTransaction.run();
}
}
protected boolean setUserTransactionAvailable(boolean available) {
boolean previousUserTransactionAvailability = ServerVMClientUserTransaction.isAvailable();
View on GitHub (pinned to e1c734241f)
Solutions
- Increase the transaction timeout with @TransactionConfiguration(timeout=...) on the entry method or quarkus.transaction.default-transaction-timeout globally
- Move slow external I/O outside the transaction boundary so the TX window stays short
- Tune the reaper (quarkus.transaction.periodic-recovery-period / reaper-related settings) and investigate why the TX ran so long
- Handle work loss idempotently — the TX rolled back, so retry the operation once the slowness is fixed
Example fix
// before
@Transactional
void importAll() { slowHttpCall(); ... } // >60s, reaper aborts
// after
@Transactional @TransactionConfiguration(timeout = 600)
void importAll() { ... } Defensive patterns
Strategy: retry
Validate before calling
int status = transactionManager.getStatus(); boolean txStillAlive = (status == jakarta.transaction.Status.STATUS_ACTIVE); // if not alive before committing, the reaper already killed it
Try / catch
try { @Transactional work } catch (RollbackException e) {
if (e.getMessage().contains("already rolled back")) { /* retry idempotently with larger timeout */ }
} Prevention
- Keep transactions shorter than the configured timeout
- Move slow HTTP/file I/O outside transaction boundaries
- Raise timeout via @TransactionConfiguration(timeout=) on the entry method
- Monitor for reaper warnings (ARJUNA012117 etc.) in logs
When it happens
Trigger: A @Transactional method runs longer than the configured transaction timeout (default 60s); the reaper rolls back and aborts the TX; when the interceptor later calls endTransaction, the thread's transaction is gone, so tm.getTransaction()==null. Also invoked from handleAsync for deferred completion.
Common situations: Slow external calls (HTTP, DB queries) inside a transaction exceeding the timeout; large batch processing in one TX; deadlock/stuck DB connection until timeout; default timeout too small for the workload.
Related errors
- Error getting the status of the current transaction
- Error getting the current transaction
- Cannot register synchronization
- Changing timeout via @TransactionConfiguration can only be d
- Syncs are not allowed because the group of synchronizations
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/18410ba32d49d207.
Report an issue: GitHub.