quarkusio/quarkus · error · SystemException
The transaction is not active!
Error message
The transaction is not active!
What it means
TransactionScopedNotifier.getTransactionId() builds the TransactionId event payload from the current JTA transaction; if TransactionImple.getTransaction() fails (no active transaction on the thread), every exception is converted into jakarta.transaction.SystemException("The transaction is not active!"). It is thrown while firing transaction-scoped observer events, meaning the code ran outside a real transaction.
Source
Thrown at extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/TransactionScopedNotifier.java:50
beforeDestroyed = Arc.container().beanManager().getEvent()
.select(TransactionId.class, BeforeDestroyed.Literal.of(TransactionScoped.class));
}
beforeDestroyed.fire(transactionId);
}
void destroyed(TransactionId transactionId) {
if (destroyed == null) {
destroyed = Arc.container().beanManager().getEvent()
.select(TransactionId.class, Destroyed.Literal.of(TransactionScoped.class));
}
destroyed.fire(transactionId);
}
TransactionId getTransactionId() throws SystemException {
try {
return new TransactionId(TransactionImple.getTransaction().toString());
} catch (Exception e) {
throw new SystemException("The transaction is not active!");
}
}
// we use this wrapper because if we fire an event with string payload then any "@Observes String payload" would be notified
public static final class TransactionId {
private final String value;
public TransactionId(String value) {
this.value = value;
}
@Override
public String toString() {
return value;
}
@OverrideView on GitHub (pinned to e1c734241f)
Solutions
- Annotate the calling method (or a wrapping method) with @Transactional so a transaction is active
- Wrap getTransactionId-dependent logic in a check for active transaction status before firing/observing
- Catch SystemException and treat it as 'no transaction' if the observer must tolerate transaction-less execution
Example fix
// before
public void doWork() { notifier.getTransactionId(); }
// after
@Transactional
public void doWork() { notifier.getTransactionId(); } Defensive patterns
Strategy: try-catch
Validate before calling
if (!TransactionManager.transactionManager().getStatus().equals(Status.STATUS_ACTIVE)) { /* skip or start a transaction first */ } Type guard
boolean hasActiveTransaction() { try { return javax.transaction.Status.STATUS_ACTIVE == com.arjuna.ats.jta.TransactionManager.transactionManager().getStatus(); } catch (Exception e) { return false; } } Try / catch
try { TransactionId id = getTransactionId(); ... } catch (SystemException e) { log.warn("no active transaction, skipping id"); } Prevention
- Annotate entry points that use transaction-scoped features with @Transactional
- Do not fire/observe transaction events from background threads without transaction propagation
- Check Status.STATUS_ACTIVE before transaction-dependent logic
When it happens
Trigger: An observer or callback tied to the transaction scope (e.g. @Observes of transaction events via TransactionScopedNotifier) executing when no JTA transaction is active on the current thread — e.g. after commit/rollback completed or code running on a non-transactional thread.
Common situations: @Transactional missing on the entry point so transaction-scoped beans/events run without a transaction; observer logic invoked after the transaction already finished; async threads detached from the transactional context.
Related errors
- No active transaction on the current thread
- Cannot use the EntityManager/Session because neither a trans
- Cannot use the EntityManager/Session because no transaction
- Unsupported value:
- seconds cannot be negative
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/ce66c7b999c99e64.
Report an issue: GitHub.