flowable/flowable-engine · error · Error

Memory limit of ${maxMemoryUsed} bytes reached

Error message

Memory limit of ${maxMemoryUsed} bytes reached

What it means

The secure JavaScript sandbox also enforces an allocation memory limit using the ThreadMXBean thread-allocated-bytes counter. In observeInstructionCount, if the bytes allocated by the script thread since it started reach maxMemoryUsed, a java.lang.Error is thrown to kill the script immediately. This prevents memory-exhaustion attacks or accidental OOM from scripts in Flowable script tasks.

Source

Thrown at modules/flowable-secure-javascript/src/main/java/org/flowable/scripting/secure/impl/SecureScriptContextFactory.java:92

        SecureScriptContext context = (SecureScriptContext) cx;

        // Time limit
        if (maxScriptExecutionTime > 0) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - context.getStartTime() > maxScriptExecutionTime) {
                throw new Error("Maximum variableScope time of " + maxScriptExecutionTime + " ms exceeded");
            }
        }

        // Memory
        if (maxMemoryUsed > 0 && threadMxBeanWrapper != null) {

            if (context.getStartMemory() <= 0) {
                context.setStartMemory(threadMxBeanWrapper.getThreadAllocatedBytes(context.getThreadId()));
            } else {
                long currentAllocatedBytes = threadMxBeanWrapper.getThreadAllocatedBytes(context.getThreadId());
                if (currentAllocatedBytes - context.getStartMemory() >= maxMemoryUsed) {
                    throw new Error("Memory limit of " + maxMemoryUsed + " bytes reached");
                }
            }

        }
    }

    // Override {@link #doTopCall(Callable, Context, Scriptable, Scriptable, Object[])}
    @Override
    protected Object doTopCall(Callable callable, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
        SecureScriptContext mcx = (SecureScriptContext) cx;
        mcx.setStartTime(System.currentTimeMillis());
        return super.doTopCall(callable, cx, scope, thisObj, args);
    }

    public int getOptimizationLevel() {
        return optimizationLevel;
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Refactor the script to avoid building large in-memory data structures; process data incrementally.
  2. Increase the maxMemoryUsed configuration if the script legitimately needs more memory.
  3. Move the heavy processing to a Java service task instead of scripting.
  4. Ensure the JVM supports com.sun.management.ThreadMXBean allocation tracking so limits behave predictably.

Example fix

// before: builds one giant string, exceeds memory limit
var s = '';
for (var i = 0; i < 100000000; i++) { s += i; }

// after: accumulate smaller, or compute without storing everything
var total = 0;
for (var i = 0; i < 1000000; i++) { total += i; }
execution.setVariable('total', total);
Defensive patterns

Strategy: try-catch

Try / catch

try {
  script.execute(execution);
} catch (Throwable t) {
  if (t instanceof Error && String(t.getMessage()).startsWith("Memory limit of")) {
    throw new FlowableException("Script exceeded allocation memory limit", t);
  }
  throw t;
}

Prevention

When it happens

Trigger: A JavaScript script task/listener allocates more memory than the configured maxMemoryUsed (flowable.script memory limit) — building huge arrays/strings, loading big data into the script, or deeply recursive structures; checked on Rhino instruction counts.

Common situations: Script concatenating or accumulating very large collections; fetching large process data into JS variables; memory limit configured too low for legitimate work; runaway recursive script.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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