Server-Side Validation
Server-side validation enforces form field constraints on the server when a form is submitted. While client-side validations provide instant feedback in the browser, they can be bypassed through API calls or browser developer tools. Server-side validation acts as an enforcement layer that cannot be circumvented.
Enabling Server-Side Validation
Server-side validation requires two things:
-
The global engine property
flowable.form-field-validation-enabledmust be set totrue. This property defaults tofalse. When disabled, all per-task validation settings are ignored and server-side validation is completely off. -
The validation property on the individual task or event must be enabled. The property accepts a boolean value or an expression (e.g.
${shouldValidate}) for conditional validation.
| Element | Property |
|---|---|
| BPMN User Task | Validate form fields (server-side) |
| BPMN Start Event | Validate start form fields (server-side) / Validate work form fields (server-side) |
| CMMN Human Task | Validate form fields (server-side) |
| CMMN Case Plan Model | Validate start form fields (server-side) / Validate work form fields (server-side) |
| CMMN User Event Listener | Validate start form fields (server-side) |
The property only appears when a form is referenced on the task or event.
What Gets Validated
When server-side validation is enabled, the following constraints are checked:
| Rule | Applies to | Form field setting | Error message |
|---|---|---|---|
| Required | All field types | Validation > Required | variable X is required |
| Min length | Text, Textarea, Password | Validation > Minimum length | Minimal text X length is Y |
| Max length | Text, Textarea, Password | Validation > Maximum length | Maximal text X length is Y |
| Min value | Number, Slider | Validation > Minimum | Minimal number X value is Y |
| Max value | Number, Slider | Validation > Maximum | Maximal number X value is Y |
| Regex pattern | Any field with Validation regex | Validation > Validation regex | the field X value does not match regular expression Y |
| Enabled check | All field types | Rendering > Enabled | variable X is not enabled and value differs |
| Ignored check | All field types | Rendering > Ignored | variable X is ignored and should not be submitted |
When multiple form fields reference the same variable, the strictest constraints are applied (e.g. the lowest minimum length and the highest maximum length).
The server also rejects variables that are not defined in the form model, returning Variable X is missing in the form model.
Buttons and Non-Input Fields
Variables set by buttons (REST buttons, service registry buttons, action buttons, and expression buttons) are recognized as part of the form model and are subject to server-side validation. However, the Required rule is never enforced on button output variables, since the user does not always directly control whether a button has been clicked.
The Enabled, Writable, and Ignored checks still apply to button output variables. For service registry and action buttons, the output can be mapped either inside the button's scope or to the root level, depending on the Map response inside scope setting.
Interaction with Ignore, Visible and Enabled
Server-side validation respects the Ignore, Visible and Enabled state of form fields:
- Disabled fields: The server rejects any changes to disabled fields. If the submitted value differs from the original, validation fails.
- Ignored fields: The server rejects submission of ignored fields entirely.
- Constraint validation: Only fields that are enabled and not ignored have their constraints (required, length, range, regex) checked.
How Expressions Are Evaluated on the Server
The enabled, ignore, and isRequired form field properties can use frontend expressions ({{...}}).
When server-side validation runs, these are converted to backend expressions (${...}) and evaluated against the submitted payload.
Key differences from frontend expression evaluation:
- Not all frontend expressions are supported — frontend expressions (
{{...}}) are converted to backend expressions (${...}) by replacing the delimiters. This means only expressions that are also valid backend expressions will work). Frontend-specific functions (e.g.flw.mapAttr(),flw.formatDate(),flw.getUser()) are not valid backend expressions. When such an expression fails to evaluate, it is silently ignored and the field falls back to its default state (see below). visibleis NOT evaluated server-side — it is purely a UI property. Onlyenabled,ignore, andisRequiredare evaluated.- Expressions must resolve to a boolean — non-boolean results cause an error.
- Context is the submitted payload only — unlike the frontend, the server only has access to the values submitted with the form, not the full UI state.
- Failed expressions are silently ignored — if an expression references a variable not present in the payload, the field falls back to its default state. No validation error is raised for the expression failure itself.
2025.2.04+ When an enabled, ignore, or isRequired expression cannot be evaluated on the server, a warning is logged that includes the property name, the expression that failed, the form field ID, and the form key. This makes it easier to identify mismatches between frontend and backend expression evaluation during development and testing. If this logging is not needed, it can be disabled by setting the log level for com.flowable.form.validation.expression to ERROR.
If an enabled or ignore expression references a variable that is not part of the form payload (e.g. $temp or $currentUser), the server-side validation will not work, because these values are not available in the back-end.
Keep these expressions simple and ensure they only reference variables that are part of the form payload.
Error Handling
When validation fails, the server returns all validation errors together. The form UI displays these errors to the user, preventing the submission from completing.
Relationship to Client-Side Validation
| Client-side | Server-side | |
|---|---|---|
| Runs in | Browser | Server |
| Feedback | Instant, as the user types | On form submission |
| Can be bypassed | Yes (API calls, dev tools) | No |
| Custom expressions | Yes | No (built-in rules only) |
Both can be used together: client-side validation for a responsive user experience, and server-side validation for enforcement.
Server-side validation only applies when submitting forms (task completion, process start, case start). Changing variables through other REST endpoints (e.g. the variable endpoints) is not subject to form validation. To enforce constraints such as min/max values or regex patterns on those endpoints, use data dictionary constraints and data contracts on the case or process model.