Field Validation 3.0.0 Is Out: What's New and How to Upgrade
Field Validation 3.0.0 rebuilds every rule on Symfony constraints and runs on Drupal 11. Read this before you run composer update on an 8.x-1.x site.
Field Validation 3.0.0 is out!! The stable release landed on October 1, 2026. The last stable release before this was 8.x-1.1, back in July 2023, so this one was a long time coming.
Most of 3.0.x was built by howard ge, who wrote the module and did the big rewrite in 2023 (yeah, before the AI revolution). This year I joined as a co-maintainer and helped get it over the line. Thanks to the Drupal AI Initiative for pushing to get a stable release out, and to Marcus Johansson for cutting the 3.0.0 release. If you’re on 8.x-1.x, there’s one thing you need to do so your site doesn’t break. Upgrade steps first, then what’s new.
Upgrading from 8.x-1.x
The short version: enable field_validation_legacy when you upgrade.
3.0.0 rebuilt every validation rule on Symfony’s Constraint API, and each rule got a new plugin ID. Your existing rule sets (field_validation.rule_set.* config) still point at the old IDs, like email_field_validation_rule. If you only update the code, those IDs stop resolving and you get a PluginNotFoundException. That takes down the rule set admin pages and validation on every entity the rule set is attached to.
The field_validation_legacy submodule ships the original 8.x-1.1 rules unchanged, under their original IDs. Enable it and your rule sets work exactly like they did before. No config edits needed, because the rule set entity itself didn’t change between 8.x-1.1 and 3.x.
The steps:
- Check your core version. 3.x needs Drupal
^10.2 || ^11. 8.x-1.x ran on Drupal 9, so if you’re still on 9 or early 10, upgrade core first. - Update the module:
composer require 'drupal/field_validation:^3.0'. It also pulls insymfony/expression-languageandsymfony/intl. - Enable the legacy submodule:
drush en field_validation_legacy, thendrush updbanddrush cex, and commit the config. Do this in the same deploy as the code update so production never runs 3.x without it. - Check who has the “administer field validation rule set” permission. More on this below. It matters more now than it did in 8.x-1.x.
- Move your rules over when you have time. The legacy submodule is a frozen copy of 8.x-1.1. It gets no new features and no fixes beyond keeping it running on supported core. Rebuild your rule sets with the new constraint rules, then uninstall it.
There’s no automatic migration from old rules to new ones yet. Some map over easily:
| 8.x-1.x rule | 3.x constraint rule |
|---|---|
| Email constraint | |
| Length | Length constraint |
| Regex | Regex constraint |
| Unique | Unique field constraint |
| Min/max item count | Count constraint |
| IP | Ip constraint |
| Must be empty | Blank constraint |
| Words blocklist | Regex constraint with “must match” unchecked |
Others, like Phone, Number of words, or Match against a field, have no direct equivalent. Keep those on legacy for now, or rebuild them with Regex, Expression, or Callback.
What’s new in 3.0.0
48 constraint-based rules. You now get Symfony’s validators straight from the UI: number comparisons (GreaterThan, LessThanOrEqual, DivisibleBy, Positive, Range), identifiers (Uuid, Ulid, Iban, Bic, Isbn, Issn, Isin, Luhn, CardScheme), formats (Json, Hostname, Ip, Cidr, CssColor, Date, DateTime, Time), locale data (Country, Language, Locale, Currency), and Drupal core’s own Email, NotNull, and UniqueField. The rule picker groups them under “Constraint rule”.
Two validate modes. Each constraint rule has a “Validate mode” setting:
- Default runs the rule through Field Validation. Role scoping, conditions, custom error messages, and tokens all work.
- Direct attaches the Symfony constraint straight to the field definition. It’s leaner, but it skips roles and conditions. If you set roles or a condition and pick Direct, the form now refuses to save instead of quietly ignoring them.
Expression and Callback rules. Expression evaluates a Symfony expression-language string against the value. Callback calls a Class::method you name. They’re handy, but they also mean anyone who can edit rule sets can run code. That’s why “administer field validation rule set” is a restricted permission and the README now spells it out. Only give it to roles you’d trust with PHP.
Regex can invert. Uncheck “Value must match the pattern to be valid” and the rule flags values that do match. Handy for blocking a forbidden word or substring (#3391589). An invalid pattern now shows a proper form error instead of a raw PHP warning (#3390907).
Drupal 11, PHP 8.4, Symfony 7. Core requirement is ^10.2 || ^11, Symfony dependencies accept ^7, and the PHP 8.4 implicit-nullable deprecations are gone.
Fixes that landed before stable:
- NotBlank now catches blank values on multi-value fields, including deltas missing from the submission (#3471408).
- Callback no longer fatals. Length, Range, and Count no longer demand both min and max. A condition pointing at a deleted field logs a warning instead of crashing the form (#3616699).
- The Country constraint plugin ID is now
SymfonyCountry, so it doesn’t collide with the Address module’sCountryconstraint. Only relevant if you referenced the ID in code.
Thanks
Thanks to howard ge for the module and the 3.x rewrite, and to everyone who sent a patch along the way: Jakub Piasecki, Marcus Johansson, Thomas Gauges, Valentin Hoarau, Pablo Urrea, Anirudh Singh, Olivier Deboyser, Taras Korpach, and Ben Stallings.
If the upgrade breaks something on your site, open an issue in the issue queue, drop a message in #field_validation on Drupal Slack. And if you’ve got an old rule with no clean 3.x equivalent, tell me about it / file a issue. That’s the list I want to work through next.