While working with Laravel 5.5 (and later versions), many developers encounter the error:
Serialization of ‘Closure’ is not allowed
This error commonly appears when caching, queuing jobs, or storing objects that contain closures. Since Laravel relies on PHP’s serialization to store cached data or queue jobs, closures cannot be serialised—leading to this issue.
This article explains why this happens, explores real-world examples, and provides solutions and best practices.
PHP’s serialization engine cannot handle closures (anonymous functions). When you attempt to cache or queue something that contains a closure, PHP throws this exception.
Laravel triggers this when you:
– Cache models/collections containing closures.
– Pass closures or objects containing closures into queued jobs.
– Cache views or configurations that internally include closures.
A developer attempted to cache FAQs with related articles:
public static function cachedFaq()
{
return Cache::remember('faq', 60 * 24 * 7, function () {
return self::with(['articles'])
->whereHas('parent', function ($query) {
$query->where('slug', 'faq');
})
->get();
});
}
Serialization of ‘Closure’ is not allowed
The developer later discovered the actual cause: they had overridden the __construct() method in their Eloquent model, which introduced a closure into the object. Because PHP cannot serialise closures, Laravel failed when attempting to cache it.
Remove or refactor the custom __construct() in the model. If you still need to prepare data for caching, convert it to an array:
return Cache::remember('faq', 60 * 24 * 7, function () {
return self::with(['articles'])
->whereHas('parent', fn($q) => $q->where('slug', 'faq'))
->get()
->toArray(); // âś… Safe for caching
});
Wrong: (passing whole $request into a job):
dispatch(new ProcessOrder($request));
Correct: (pass only needed fields):
dispatch(new ProcessOrder($request->only(['order_id', 'amount'])));
Wrong:
Cache::put('homepage', view('home'), 60);
Correct:
Cache::put('homepage', view('home')->render(), 60);
Wrong:
Cache::put('users', User::with('roles')->get(), 60);
Correct:
Cache::put('users', User::with('roles')->get()->toArray(), 60);
Wrong (config/services.php):
'payment' => function() { return new PaymentService(); },
Correct:
'payment' => App\Services\PaymentService::class,
The “Serialization of ‘Closure’ is not allowed” error is common but easily preventable once you know the root cause. The fix is to avoid caching or queuing closures directly and instead pass plain data, arrays, or strings.
By following the above best practices, you’ll ensure your Laravel apps remain stable, cache-friendly, and queue-safe.
Work with our skilled Laravel developers to accelerate your project and boost its performance.
Hire Laravel Developer