# Illuminate\Queue\MaxAttemptsExceededException: App\Jobs\SendNotification has been attempted too many times or run too long. The job may have been previously processed by a worker that was forcefully terminated.

- **ID:** `php/laravel-queue-worker-sigterm-timeout`
- **Domain:** php
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 85%

## Root Cause

A Laravel queue worker received a SIGTERM signal (e.g., during deployment or scaling) while processing a job, causing the job to be marked as failed or re-attempted without proper release, exceeding the maximum attempts limit.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| laravel 10 | active | — | — |
| laravel 11 | active | — | — |
| php 8.2 | active | — | — |
| php 8.3 | active | — | — |
| horizon 5.21 | active | — | — |

## Workarounds

1. **Implement a `failed` method in the job to handle the exception gracefully, and use `php artisan queue:retry all` to re-run failed jobs after ensuring workers are stable.** (90% success)
   ```
   Implement a `failed` method in the job to handle the exception gracefully, and use `php artisan queue:retry all` to re-run failed jobs after ensuring workers are stable.
   ```
2. **Add a `pcntl_signal` handler in the job's `handle` method to catch SIGTERM and release the job back to the queue: `pcntl_signal(SIGTERM, function () { $this->release(30); });`** (85% success)
   ```
   Add a `pcntl_signal` handler in the job's `handle` method to catch SIGTERM and release the job back to the queue: `pcntl_signal(SIGTERM, function () { $this->release(30); });`
   ```

## Dead Ends

- **Increasing the `--tries` option on the queue worker to a very high number** — The issue is not about the number of attempts but about the job being incorrectly marked as failed due to SIGTERM; increasing tries may delay the failure but not prevent it. (80% fail)
- **Disabling the `force` option in deploy scripts that send SIGTERM** — SIGTERM is necessary for graceful shutdown; disabling it can cause longer downtimes or zombie processes. (70% fail)
