required
Requires the field to be present and not null, an empty string, an empty array or a pathless upload.
requiredErrors
Nothing on its own; when the rule set is run through validate() or a form request, a failure raises Illuminate\Validation\ValidationException.
The field under validation must be present in the input data and not empty. Laravel treats a value as empty when it is null, an empty string, an empty array or empty Countable, or an uploaded file with no path. A string of only whitespace is empty too — the check trims before comparing.
What is not empty
The integer 0, the string "0", false, and an array containing a single empty string all pass. This surprises people writing 'quantity' => 'required' and expecting zero to be rejected; use min:1 for that.
Where people get bitten
Laravel's global middleware includes ConvertEmptyStringsToNull, so a blank text input arrives as null. Either way required rejects it, but that is why the field you can see in the payload still fails.
Unchecked HTML checkboxes are never submitted at all, so required on one always fires. Use accepted for consent boxes.
required is an implicit rule: it runs even when the attribute is absent. Almost every other rule — email, unique, min — silently skips absent or empty values, which is why 'email' => 'email' alone lets an empty payload through.
If you need "present but may be blank", combine present with nullable instead.
Example
<?php
use Illuminate\Support\Facades\Validator;
$validator = Validator::make(
['name' => '', 'tags' => [], 'quantity' => 0],
[
'name' => 'required',
'tags' => 'required',
'quantity' => 'required',
]
);
var_dump($validator->fails());
print_r($validator->errors()->keys());
// bool(true)
// Array
// (
// [0] => name
// [1] => tags
// )
//
// quantity passes: integer 0 is not "empty".When to use it
- Rejecting a sign-up submission where the name box was left blank.
- Guaranteeing an API POST body carries an order_id before any database work starts.
- Making a document upload mandatory on a claims submission endpoint.
- Ensuring a multi-select sends at least one option rather than an empty array.
Frequently asked questions
Why does required pass when the value is 0 or false?
Because neither is on Laravel's empty list — only null, an empty string, an empty array or Countable, and a pathless uploaded file count as empty. To reject zero, add a rule that expresses the real constraint: `integer|min:1` for a quantity, `accepted` for a checkbox that must be ticked.
What is the difference between required and nullable?
They are opposites: `required` rejects null, `nullable` permits it. They should never appear on the same field. If you want a field that may be omitted entirely, use `sometimes` rather than `nullable`, since most rules already skip absent keys.
Why does my required checkbox always fail validation?
An unchecked checkbox is not submitted by the browser at all, so the field is absent and `required` fires. Use the `accepted` rule for terms-of-service boxes, or render a hidden input with value 0 immediately before the checkbox so something is always posted.
More examples
Exactly what counts as empty
The four failing cases are exactly the four the documentation lists (null, empty string, empty array, pathless file), plus whitespace-only strings which are trimmed before the check. Note that `false` and `0` pass — if a boolean toggle must be explicitly sent, `required|boolean` is right, but if it must be true you want `accepted`.
<?php
use Illuminate\Support\Facades\Validator;
$cases = [
'null' => null,
'empty string' => '',
'only spaces' => ' ',
'integer zero' => 0,
'string zero' => '0',
'false' => false,
'empty array' => [],
'array of one' => [''],
];
foreach ($cases as $label => $value) {
$passes = Validator::make(['v' => $value], ['v' => 'required'])->passes();
echo str_pad($label, 14) . ($passes ? 'passes' : 'FAILS') . PHP_EOL;
}
// null FAILS
// empty string FAILS
// only spaces FAILS
// integer zero passes
// string zero passes
// false passes
// empty array FAILS
// array of one passesrequired inside a form request, including array members
`tags => required|array|min:1` rejects both a missing key and an empty array, while `tags.* => required` rejects an array that contains blank entries such as `['php', '']`. Without the `tags.*` line, `['']` would pass because it has a count of one.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StorePostRequest extends FormRequest
{
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:255'],
'body' => ['required', 'string'],
'cover' => ['required', 'file', 'max:2048'],
'tags' => ['required', 'array', 'min:1'],
'tags.*' => ['required', 'string', 'max:40'],
];
}
}
// In the controller:
//
// public function store(StorePostRequest $request)
// {
// $validated = $request->validated();
//
// echo $validated['title'];
// print_r($validated['tags']);
// }Present but allowed to be blank
This is the distinction people usually want when they reach for `required` and then fight it. `present` asserts the key exists in the payload; `nullable` permits its value to be null. `required` is the union of both plus a non-emptiness check.
<?php
use Illuminate\Support\Facades\Validator;
// "required" rejects a null nickname.
$a = Validator::make(['nickname' => null], ['nickname' => 'required']);
// "present|nullable" insists the key is sent, but allows it to be blank.
$b = Validator::make(['nickname' => null], ['nickname' => 'present|nullable|string']);
// The key is missing entirely, so "present" fails.
$c = Validator::make([], ['nickname' => 'present|nullable|string']);
var_dump($a->passes()); // bool(false)
var_dump($b->passes()); // bool(true)
var_dump($c->passes()); // bool(false)
Discussion