Skip to main content

What are custom validation rules?

Laravel ships with a rich set of built-in validation rules, but you will sometimes need validation logic specific to your application. Custom validation rules let you define reusable validation logic as a class or closure and use it exactly like a standard rule. There are two main ways to define a custom rule:
  • Rule objects — highly reusable and easy to test in isolation
  • Closures — concise, suitable for one-off rules

Rule objects

Generating a rule class

Use the make:rule Artisan command to generate a new rule class. The generated class is placed in the app/Rules directory.

Implementing the ValidationRule interface

Implement the validate method in the generated class. This method calls the $fail closure when validation fails.
The string passed to $fail may use the :attribute placeholder, which Laravel replaces with the field name.

Applying a rule object

Pass an instance of the rule object in the validation array.
The same approach works inside a FormRequest’s rules() method.

Using translation keys for error messages

Instead of hard-coding error messages, you can use translation keys.
Add the message to lang/en/validation.php:

Reporting multiple errors

Call $fail more than once to report multiple errors for a single field.

Closure-based rules

For simple rules you only need once, define the logic inline as a closure instead of creating a class.
Closure rules are convenient for one-off logic, but they are harder to reuse and test independently. If the same rule appears in more than one place, extract it into a rule object.

Implicit rules (run even when the value is empty)

By default, custom rules are skipped when the field is missing or empty. To run the rule regardless, add the --implicit flag when generating the class.
The generated class implements ImplicitRule. This interface has no additional methods — it is a marker interface that signals Laravel to run the rule on empty values too.
ImplicitRule only tells Laravel to run the rule on empty values. Whether empty values actually fail is still determined by your validate method implementation.

Accessing other data during validation

DataAwareRule — accessing the full form data

When your rule logic depends on another field’s value, implement DataAwareRule. Laravel automatically calls setData before validation begins.
Usage:

ValidatorAwareRule — accessing the validator instance

To access the full validator (including errors from other fields or custom messages), implement ValidatorAwareRule.
DataAwareRule and ValidatorAwareRule can be implemented together on the same class. Laravel will inject both the data and the validator instance.

Practical example — tenant-scoped unique constraint

A common multi-tenant requirement: a value must be unique within a tenant’s scope.
1

Create the rule class

2

Use the rule in a FormRequest

3

Exclude the current record on update

When updating an existing record, exclude its own ID from the uniqueness check.

Registering rules via the service provider

Validator::extend() — adding a string-based rule

Validator::extend() lets you register a rule that can be referenced as a plain string (e.g. 'rule_name'). Register it in the boot() method of AppServiceProvider.
Use the rule as a string:
Validator::extend() is an older registration style. For new code, prefer rule objects that implement ValidationRule.

Adding a fluent API via Rule macros

Add a macro to the Rule class so the rule can be called as Rule::myRule().

How Laravel invokes custom rules internally

When the validator processes an attribute, validateUsingCustomRule() is called for any rule implementing ValidationRule. Here is a simplified version:
The ImplicitRule check determines whether the rule runs on empty values:

Validation (basics)

Standard validation in controllers and form requests.
Last modified on March 29, 2026