Summary
Three UUID-based failed job providers use json_decode($payload, true)['uuid'] without checking if json_decode returned null. If the queue backend delivers a corrupted payload, the provider crashes, and the failed job record is permanently lost — the safety net has a hole.
Version: 13.3.0
Affected files
1. FileFailedJobProvider.php line 59:
$id = json_decode($payload, true)['uuid'];
2. DatabaseUuidFailedJobProvider.php line 58:
'uuid' => $uuid = json_decode($payload, true)['uuid'],
3. DynamoDbFailedJobProvider.php line 60:
$id = json_decode($payload, true)['uuid'];
The non-UUID DatabaseFailedJobProvider is not affected — it stores the raw payload without parsing.
How it fails
If json_decode() returns null (corrupted/truncated payload):
null['uuid'] emits a warning and returns null in PHP 8+
- DatabaseUuidFailedJobProvider: inserts
null into UUID column → likely constraint violation → exception
- DynamoDbFailedJobProvider: passes
null as DynamoDB 'S' attribute → AWS SDK throws
- FileFailedJobProvider: stores
null as job ID → corrupts the failed jobs file
In all cases, the exception propagates through WorkCommand::logFailedJob() (which has no try/catch around the log() call), and the failed job record is never written.
When it triggers
The $payload comes from $event->job->getRawBody() — raw bytes from the queue backend. While Laravel always creates valid JSON payloads internally, the data could be corrupted by:
- Redis network issues during write/read
- Database row corruption
- SQS message body truncation
- Custom queue drivers with payload bugs
Impact
The failed jobs table is the safety net for jobs that fall through the cracks. When the safety net itself crashes, you lose both the job execution AND the audit trail that it failed. The job enters a silent limbo — no retry button, no failure record, no alert.
Suggested fix
$data = json_decode($payload, true);
$id = $data['uuid'] ?? null;
Or more defensively:
$data = json_decode($payload, true);
$id = is_array($data) ? ($data['uuid'] ?? 'unknown-' . Str::uuid()) : 'corrupt-' . Str::uuid();
Summary
Three UUID-based failed job providers use
json_decode($payload, true)['uuid']without checking ifjson_decodereturned null. If the queue backend delivers a corrupted payload, the provider crashes, and the failed job record is permanently lost — the safety net has a hole.Version: 13.3.0
Affected files
1.
FileFailedJobProvider.phpline 59:2.
DatabaseUuidFailedJobProvider.phpline 58:3.
DynamoDbFailedJobProvider.phpline 60:The non-UUID
DatabaseFailedJobProvideris not affected — it stores the raw payload without parsing.How it fails
If
json_decode()returnsnull(corrupted/truncated payload):null['uuid']emits a warning and returnsnullin PHP 8+nullinto UUID column → likely constraint violation → exceptionnullas DynamoDB 'S' attribute → AWS SDK throwsnullas job ID → corrupts the failed jobs fileIn all cases, the exception propagates through
WorkCommand::logFailedJob()(which has no try/catch around thelog()call), and the failed job record is never written.When it triggers
The
$payloadcomes from$event->job->getRawBody()— raw bytes from the queue backend. While Laravel always creates valid JSON payloads internally, the data could be corrupted by:Impact
The failed jobs table is the safety net for jobs that fall through the cracks. When the safety net itself crashes, you lose both the job execution AND the audit trail that it failed. The job enters a silent limbo — no retry button, no failure record, no alert.
Suggested fix
Or more defensively: