quarkusio/quarkus · error · IllegalStateException
Syncs are not allowed to be registered when the transaction
Error message
Syncs are not allowed to be registered when the transaction is in state
What it means
Quarkus's TSR registerInterposedSynchronization only accepts new interposed synchronizations while the transaction is STATUS_ACTIVE or STATUS_PREPARING. Any other state (e.g. PREPARED, COMMITTING, ROLLED_BACK, ROLLEDBACK, COMMITTED) is too late, and the code throws this IllegalStateException, appending the offending status to the message. It prevents silent loss of cleanup callbacks that would never run.
Source
Thrown at extensions/narayana-jta/runtime/src/main/java/io/quarkus/narayana/jta/runtime/internal/tsr/AgroalOrderedLastSynchronizationList.java:143
* <p>
*
* @param synchronization The synchronization to register
* @throws IllegalStateException if the transaction is in the wrong state:
* <ol>
* <li>the transaction has already prepared;
* <li>the transaction is marked rollback only
* <li>the group that the synchronization should belong to has already been processed
* </ol>
*/
public void registerInterposedSynchronization(Synchronization synchronization) {
int status = tsr.getTransactionStatus();
switch (status) {
case Status.STATUS_ACTIVE:
case Status.STATUS_PREPARING:
break;
default:
throw new IllegalStateException(REGISTER_SYNC_ERROR + status);
}
// add the synchronization to the group that matches this package and, if there is no such group
// then add it to the catch-all group (otherSyncs)
String packageName = synchronization.getClass().getName();
SynchronizationGroup synchGroup = otherSynchs;
for (SynchronizationGroup g : synchGroups) {
if (g.shouldAdd(packageName)) {
synchGroup = g;
break;
}
}
synchGroup.add(synchronization);
}
/**View on GitHub (pinned to e1c734241f)
Solutions
- Register interposed synchronizations while the transaction is active, earlier in the business flow
- Check transaction status before registering and skip/degrade gracefully if the TX is terminating
- Avoid acquiring new TX-enlisted resources inside completion callbacks or after commit/rollback started
- If triggered by a driver/extension, ensure resources are closed before the transaction completes (e.g. proper request-scope cleanup)
Example fix
// before
int status = tx.getStatus();
if (status != Status.STATUS_ACTIVE) { /* still registers -> throws */ }
registerInterposedSynchronization(sync);
// after
int status = tx.getStatus();
if (status == Status.STATUS_ACTIVE || status == Status.STATUS_PREPARING) {
registerInterposedSynchronization(sync);
} Defensive patterns
Strategy: validation
Validate before calling
int st = transactionManager.getStatus();
boolean registrationAllowed =
st == jakarta.transaction.Status.STATUS_ACTIVE || st == jakarta.transaction.Status.STATUS_PREPARING; Try / catch
try { registerInterposed(sync); } catch (IllegalStateException e) {
if (e.getMessage().startsWith("Syncs are not allowed to be registered")) { /* run cleanup directly instead */ }
} Prevention
- Check tx status before registering interposed synchronizations
- Complete all resource enlistment while the TX is ACTIVE
- Don't acquire TX-enlisted resources in async tasks racing the commit
- Close resources before commit/rollback starts
When it happens
Trigger: Calling registerInterposedSynchronization(synchronization) when tx.getStatus() is not ACTIVE or PREPARING — e.g. registering during commit/rollback completion, or after the transaction already terminated.
Common situations: Connection close/cleanup handlers running after the TX decided its fate; resource enlistment triggered lazily during commit; asynchronous tasks completing and registering syncs after the TX ended; reaper-rolled-back transactions still being enlisted by slow code.
Related errors
- Syncs are not allowed because the group of synchronizations
- Cannot register synchronization
- Error getting the status of the current transaction
- Error getting the current transaction
- Transaction was already rolled back (e.g., by the transactio
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/d9cdc9b8bb5c1cd0.
Report an issue: GitHub.