Description
Laravel Version
11.32.0
PHP Version
8.3.23
Database Driver & Version
No response
Description
Binary files (e.g., PNG, XLSX) served via response()->download() or Storage::disk(...)->download() are downloaded with the correct file size, but are corrupted and unreadable. This issue did not occur in earlier versions of Laravel or PHP.
When replaced with a manual download using readfile() and header(), the file downloads correctly.
Laravel & PHP Version
- Laravel: 11.32.0
- PHP: 8.3.23 (cli)
- Flysystem: league/flysystem v3.30.0
- Symfony/http-foundation: v7.3.1
- No middleware or response modification involved
Steps To Reproduce
Reproduction Steps :
return Storage::disk('local')->download('export/sample.png');
// Even when switching to:
return response()->download(storage_path('app/export/sample.png'));
// the file downloads but is unreadable (corrupted).
Working Manual Fix :
$path = storage_path('app/export/sample.png');
if (ob_get_level()) ob_end_clean();
header('Content-Type: ' . mime_content_type($path));
header('Content-Disposition: attachment; filename="' . basename($path) . '"');
header('Content-Length: ' . filesize($path));
readfile($path);
exit;
Notes:
- File size is identical in both versions.
- Tried with various files: PNG, PDF, DOCX.
- Issue persists even after clearing Laravel config, route, and view caches.
- No middleware or buffering logic interferes.
- Confirmed both on local and production environment.
- Switching away from Flysystem (from SFTP to local) does not fix the issue.
Suggested Fix:
Please review changes in:
• StreamedResponse usage in Laravel 11
• readStream() handling in Flysystem 3
• MIME/header management in Laravel’s response wrapping
A return to fpassthru() or readfile()-based binary streaming may solve this.
Thank You 🙏
I’m happy to help test any patch or proposed fix.