{"record":{"id":"9d9beb07029f3474","repo":"flowable/flowable-engine","slug":"systemexception-while-registering-synchronization","errorCode":null,"errorMessage":"SystemException while registering synchronization ","messagePattern":"SystemException while registering synchronization ","errorType":"exception","errorClass":"org.flowable.common.engine.api.FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/jta/JtaTransactionContext.java","lineNumber":82,"sourceCode":"            return transactionManager.getTransaction();\n        } catch (SystemException e) {\n            throw new FlowableException(\"SystemException while getting transaction \", e);\n        }\n    }\n\n    @Override\n    public void addTransactionListener(TransactionState transactionState, final TransactionListener transactionListener) {\n\n        Transaction transaction = getTransaction();\n        CommandContext commandContext = Context.getCommandContext();\n        try {\n            transaction.registerSynchronization(new TransactionStateSynchronization(transactionState, transactionListener, commandContext));\n        } catch (IllegalStateException e) {\n            throw new FlowableException(\"IllegalStateException while registering synchronization \", e);\n        } catch (RollbackException e) {\n            throw new FlowableException(\"RollbackException while registering synchronization \", e);\n        } catch (SystemException e) {\n            throw new FlowableException(\"SystemException while registering synchronization \", e);\n        }\n    }\n\n    public static class TransactionStateSynchronization implements Synchronization {\n\n        protected final TransactionListener transactionListener;\n        protected final TransactionState transactionState;\n        private final CommandContext commandContext;\n\n        public TransactionStateSynchronization(TransactionState transactionState, TransactionListener transactionListener, CommandContext commandContext) {\n            this.transactionState = transactionState;\n            this.transactionListener = transactionListener;\n            this.commandContext = commandContext;\n        }\n\n        @Override\n        public void beforeCompletion() {\n            if (TransactionState.COMMITTING == transactionState || TransactionState.ROLLINGBACK == transactionState) {","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/jta/JtaTransactionContext.java#L64-L100","documentation":"Flowable wraps the JTA TransactionManager's registerSynchronization() failures into a FlowableException. A SystemException from the underlying transaction manager signals that the transaction service itself failed unexpectedly (internal transaction manager error, wrongly configured TM, or no active transaction support). Flowable rethrows it so the command fails and the engine can roll back cleanly.","triggerScenarios":"Calling addTransactionListener to register a TransactionStateSynchronization when the JTA transaction manager is in a broken/failed state; registerSynchronization() on jakarta/javax.transaction.Transaction throws SystemException.","commonSituations":"Misconfigured JTA transaction manager (e.g. Atomikos/Narayana/Bitronix failing to boot), using the engine outside a proper JTA environment, transaction already marked rollback-only or TM internal failure, classpath mixing javax and jakarta transaction APIs.","solutions":["Inspect the cause chain (getCause()) for the underlying SystemException message from the JTA transaction manager and fix the TM configuration","Verify the JTA TransactionManager is properly initialized and accessible before starting commands (e.g. Atomikos/Narayana startup logs)","Ensure a transaction is actually active when the command runs; do not invoke engine commands outside a JTA transaction in JTA mode","Check for javax.transaction vs jakarta.transaction duplication on the classpath (Flowable version mismatch with app server)","Enable debug logging on org.flowable.common.engine.impl.cfg.jta to see the exact failing transaction state"],"exampleFix":"// before: engine in JTA mode but no TM registered\ncfg.setTransactionManager(null);\n// after\nBitronixTransactionManager tm = TransactionManagerServices.getTransactionManager();\ncfg.setTransactionManager(tm);","handlingStrategy":"try-catch","validationCode":"// before executing commands in JTA mode\ntry {\n    jakarta.transaction.Transaction tx = transactionManager.getTransaction();\n    if (tx == null) throw new IllegalStateException(\"No active JTA transaction\");\n} catch (SystemException e) {\n    throw new IllegalStateException(\"Transaction manager unhealthy: \" + e.getMessage(), e);\n}","typeGuard":null,"tryCatchPattern":"try {\n    flowableCommand.execute(...);\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"SystemException while registering synchronization\")) {\n        // inspect e.getCause(); mark transaction rollback-only or fail request\n        transactionManager.setRollbackOnly();\n    }\n    throw e;\n}","preventionTips":["Verify the JTA TransactionManager is started and healthy before running engine commands","Always run Flowable commands inside an active JTA transaction when using JtaTransactionContext","Keep javax/jakarta transaction API versions consistent with your Flowable version","Watch TM logs for startup failures and rollback-only marks"],"tags":["jta","transaction","synchronization","flowable"],"backgroundTag":"invalid-state-transition","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}