flowable/flowable-engine · warning

Error while waiting for global acquire lock for engine {}

Error message

Error while waiting for global acquire lock for engine {}

What it means

WARN log from the timer-job acquisition runnable while waiting for the global acquire lock: a non-FlowableException was thrown during the lock-wait phase and it is logged because it likely indicates a real problem, not the regular (expected) lock-contention path. The cycle simply continues and retries the lock next round.

Source

Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/asyncexecutor/AcquireTimerJobsRunnable.java:173

        long millisToWait = 0L;

        try {

            boolean globalAcquireLockEnabled = configuration.isGlobalAcquireLockEnabled();
            if (globalAcquireLockEnabled) {

                // When running with global acquire lock, we only need to have the lock during the acquire.
                // In the move phase, other nodes can already acquire timer jobs themselves (as the lock is free).
                try {
                    timerJobs = lockManager.waitForLockRunAndRelease(configuration.getLockWaitTime(), () -> {
                        return commandExecutor.execute(new AcquireTimerJobsWithGlobalAcquireLockCmd(asyncExecutor));
                    });

                } catch (Exception e) {
                    // Don't do anything, lock will be tried again next time

                    if (!(e instanceof FlowableException)) { // FlowableException doesn't need to be logged, could be regular lock logic
                        LOGGER.warn("Error while waiting for global acquire lock for engine {}", getEngineName(), e);
                    }
                }

            } else {
                timerJobs = commandExecutor.execute(new AcquireTimerJobsCmd(asyncExecutor));

            }

            if (!timerJobs.isEmpty()) {
                List<TimerJobEntity> finalTimerJobs = timerJobs;
                moveTimerJobsExecutorService.execute(() -> {
                    executeMoveTimerJobsToExecutableJobs(finalTimerJobs);
                });
            }

            // if all jobs were executed
            millisToWait = asyncExecutor.getDefaultTimerJobAcquireWaitTimeInMillis();
            int nrOfJobsAcquired = timerJobs.size();

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Inspect the chained exception to find why the lock wait failed
  2. Verify the lock manager's storage (e.g. ACT_RU_ENTITYLINK/lock table or external store) exists and is reachable
  3. Ensure custom lock managers only throw FlowableException for expected lock contention
  4. Retry — the runnable deliberately retries the lock on the next acquisition cycle

Example fix

// before
class MyLockManager implements FlowableLockManager { public void acquireLock(...) { throw new RuntimeException("lock busy"); } }
// after
public void acquireLock(...) { if (locked) { throw new FlowableException("lock busy"); } }
Defensive patterns

Strategy: try-catch

Validate before calling

// verify lock table reachability before enabling global lock
try (Connection c = dataSource.getConnection(); Statement s = c.createStatement()) { s.executeQuery("SELECT 1 FROM ACT_RU_JOB LIMIT 1"); }

Try / catch

try {
    lockManager.acquireLock(...);
} catch (FlowableException expectedLockContention) {
    // normal: retry next cycle
} catch (RuntimeException e) {
    log.warn("lock wait infrastructure failure", e);
}

Prevention

When it happens

Trigger: Acquiring the global lock (e.g. via the lock manager/command) throws a non-Flowable exception — infrastructure failures, JDBC errors from the lock table, or a custom lock manager raising unexpected exceptions.

Common situations: Lock table missing or unreachable; database outage during lock acquisition; custom FlowableLockManager implementations throwing raw RuntimeExceptions.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/9d24ccea11e1dbd0. Report an issue: GitHub.