flowable/flowable-engine · error · FlowableContentNotSupportedException

The provided body contains a serialized object for which…

Error message

The provided body contains a serialized object for which the class was not found: " + ioe.getMessage()

What it means

FlowableContentNotSupportedException thrown when deserializing a variable body whose Java class is not on the REST server's classpath. The REST API deserializes serialized Java objects sent as binary variables; if the object's class cannot be loaded, the request is rejected. This protects against silently accepting an unusable variable value.

Solutions

  1. Ensure the serialized class (and its package) is present on the server's classpath, e.g. add the client's domain jar to flowable-rest's WEB-INF/lib
  2. Prefer sending JSON or primitive values instead of raw Java-serialized objects
  3. If the class was refactored, re-serialize the variable with the new class name or use a serialization filter/Compatibility mode
  4. Check that client and server share the same version of the library defining the class

Example fix

// before
classpath: flowable-rest.war (no domain classes)
ObjectOutputStream oos = new ObjectOutputStream(out); oos.writeObject(myCustomDto);
// after
// add domain-classes.jar to flowable-rest/WEB-INF/lib so ClassNotFoundException disappears
Defensive patterns

Strategy: validation

Validate before calling

Class<?> c = null;
try { c = Class.forName(myDto.getClass().getName(), false, Thread.currentThread().getContextClassLoader()); } catch (ClassNotFoundException ignored) {}
if (c == null) throw new IllegalStateException("Class " + myDto.getClass().getName() + " must be on the flowable-rest server classpath");

Type guard

static boolean isSerializableSafe(Object o) { return o instanceof String || o instanceof Number || o instanceof Boolean || o instanceof byte[]; }

Try / catch

try {
    restClient.setBinaryVariable(executionId, name, body);
} catch (HttpServerErrorException | HttpClientErrorException e) {
    if (e.getResponseBodyAsString().contains("class was not found")) { /* fall back to JSON transport */ }
}

Prevention

When it happens

Trigger: POST/PUT of a binary variable with a Java-serialized object (Content-Type application/x-java-serialized-object) whose class was removed from the server or never deployed there.

Common situations: Client serializes a custom POJO that exists on the client but not in the flowable-rest webapp's classpath; server upgraded and the class was renamed/moved; different library versions on client and server.

Related errors


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

Appendix: source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/BaseExecutionVariableResource.java:187

            } else {
                throw new FlowableContentNotSupportedException("Serialized objects are not allowed");
            }

            RestVariable variable = null;
            
            if (!async) {
                variable = getVariableFromRequestWithoutAccessCheck(execution, variableName, scope, false);
                
                // We are setting the scope because the fetched variable does not have it
                variable.setVariableScope(scope);
            }
            
            return variable;

        } catch (IOException ioe) {
            throw new FlowableIllegalArgumentException("Could not process multipart content", ioe);
        } catch (ClassNotFoundException ioe) {
            throw new FlowableContentNotSupportedException("The provided body contains a serialized object for which the class was not found: " + ioe.getMessage());
        }

    }

    protected RestVariable setSimpleVariable(RestVariable restVariable, Execution execution, boolean isNew, boolean async) {
        if (restVariable.getName() == null) {
            throw new FlowableIllegalArgumentException("Variable name is required");
        }

        // Figure out scope, revert to local if omitted
        RestVariableScope scope = restVariable.getVariableScope();
        if (scope == null) {
            scope = RestVariableScope.LOCAL;
        }

        Object actualVariableValue = restResponseFactory.getVariableValue(restVariable);
        setVariable(execution, restVariable.getName(), actualVariableValue, scope, isNew, async);

View on GitHub (pinned to d6d39ce1c6)