To validate an uploaded image in Laravel 13, use the image rule with max (kilobytes) and dimensions, or the fluent File::image() builder. Add mimes if you want to allow only specific formats, then store the file under a generated name.
What do you need before you start?
- Laravel 13 on PHP 8.3 or newer
- A form with
enctype="multipart/form-data"and a file input namedavatar
What does the image rule accept?
The image rule accepts jpg, jpeg, png, bmp, gif, webp, avif, heic and heif files. SVG is rejected unless you write image:allow_svg, because SVG files can contain markup.
How do you validate an image with string rules?
$request->validate([
'avatar' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
]);Here max:2048 means 2048 kilobytes (2 MB). The mimes rule inspects the file contents, not only the name the client sent.
How do you limit width, height or aspect ratio?
Use the dimensions rule with named constraints such as min_width, max_width, min_height, max_height, width, height and ratio.
$request->validate([
'banner' => ['required', 'image', 'max:4096', 'dimensions:min_width=800,min_height=400,ratio=2/1'],
]);How do you use the fluent File rule?
The fluent builder keeps the constraints readable and chainable.
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;
$request->validate([
'avatar' => [
'required',
File::image()
->max(2048)
->dimensions(
Rule::dimensions()->maxWidth(2000)->maxHeight(2000)
),
],
]);How do you validate multiple images?
Validate the array and each item separately with a wildcard.
$request->validate([
'photos' => ['required', 'array', 'max:5'],
'photos.*' => ['image', 'mimes:jpg,jpeg,png', 'max:2048'],
]);How do you put it in a form request?
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\File;
class UpdateAvatarRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'avatar' => ['required', File::image()->max(2048)],
];
}
public function messages(): array
{
return [
'avatar.max' => 'The avatar must be 2 MB or smaller.',
];
}
}How do you store the file safely?
Never use the client file name. Let Laravel generate one.
public function update(UpdateAvatarRequest $request)
{
$path = $request->file('avatar')->store('avatars', 'public');
$request->user()->update(['avatar_path' => $path]);
return back()->with('status', 'Avatar updated.');
}The Laravel documentation warns that a file can pass content checks and still carry a PHP payload. Keep uploads under generated names and deny PHP execution in upload directories.
How do you verify it works?
Fake the disk and upload test files.
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
public function test_avatar_must_be_an_image(): void
{
Storage::fake('public');
$this->actingAs(User::factory()->create())
->put('/avatar', ['avatar' => UploadedFile::fake()->create('notes.pdf', 100)])
->assertSessionHasErrors('avatar');
$this->actingAs(User::factory()->create())
->put('/avatar', ['avatar' => UploadedFile::fake()->image('me.png', 300, 300)])
->assertSessionHasNoErrors();
}What are the common mistakes?
- Setting
maxin megabytes. It is in kilobytes - Also check PHP
upload_max_filesizeandpost_max_size; PHP can reject large files before Laravel validates - Allowing SVG without sanitizing it
- Trusting the client MIME type or extension alone
FAQ
What is the difference between image and mimes?
image checks that the file is a supported image type. mimes narrows it to the extensions you list.
Why does validation fail for a large photo?
Either it exceeds your max rule or PHP upload limits blocked it first.
Can I allow SVG?
Yes, with image:allow_svg, but only if you trust or sanitize the files.



