Illuminate\Queue\MaxAttemptsExceededException: App\Jobs\ProcessOrder has been attempted too many times or run too long
ID: php/laravel-queue-failed
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 11 | active | — | — | — |
Root Cause
Laravel queue job failures happen when a job exceeds its maximum retry attempts or timeout. Root causes include unhandled exceptions in job logic, external service timeouts, database deadlocks, or insufficient memory for the queue worker process.
genericWorkarounds
-
88% success Implement proper error handling with retry backoff and failed() method
Define public $tries = 3 and public $backoff = [10, 60, 300] for exponential backoff. Implement the failed(Throwable $exception) method to log errors and notify. Use specific try/catch blocks for retryable errors (throw to retry) vs permanent failures (use $this->fail()).
-
85% success Use queue:retry and monitor failed_jobs table to diagnose and fix root cause
Check failed jobs with 'php artisan queue:failed'. Examine the exception and payload. Fix the underlying issue (e.g., fix external service URL, add missing data validation). Retry specific jobs with 'php artisan queue:retry {id}' or all with 'php artisan queue:retry all'. Set up Horizon for real-time monitoring.
Dead Ends
Common approaches that don't work:
-
Setting tries to an extremely high number or infinite retries
75% fail
Setting a very high retry count for a job with a persistent error (e.g., invalid data, permanently unavailable service) wastes queue resources and can create a backlog that delays other jobs. The failing job will keep consuming worker capacity.
-
Catching all exceptions silently inside the job handle method
80% fail
Catching and swallowing all exceptions prevents the job from being marked as failed, making it appear successful when it actually did nothing. Failed jobs table will not contain the error, and monitoring/alerting will not trigger. Data will be silently lost.