ARTICLE AD BOX
In production you should NOT rely on webserver file access to storage/app (that's why you get 404). Instead store export files on the local disk and serve them through a Laravel route that checks auth/signature and streams the file (or use a temporary signed URL). That keeps the file private while allowing downloads in production.
Why this happens
In development Laravel's server, local file access (or a symlink) can make files appear to be available. In production your web server (nginx/apache) will only serve files from public/, and a URL returned to the browser that points to storage/app/..... will 404 unless you made the file publicly available (public/storage symlink) - which you don’t want.
Also if the export runs on a queue on a different machine than the web node, a local disk file won't be accessible from the web node.
Recommended solution
Store the exported file on the local disk (storage/app/....) so it remains private.
Create a signed or authenticated route that streams the file via Storage::disk('local')->download(...) (or returns a StreamedResponse). Use URL::temporarySignedRoute for time-limited access.
Ensure exports and the web process share the same filesystem (or use a shared disk) and give correct permissions.
2 Comments
Fun Fact: I did not use AI.... I used Translation (DeepL not ChatGPT xD) because I wrote it in German.. Even tho you are a Moderator, you guys are more into punishing and terrorizing people than solving Problems on Stackoverflow, thats crazy. If you insist i wrote it with AI cause one guy said so, delete the answer and punish me lol
2025-11-27T11:23:41.9Z+00:00

