valet: 404 for files in public/ (LaravelValetDriver)
I always get a status code 404 for existing files which are directly located under public/ on a fresh install (favicon.ico, robots.txt), but the files are delivered. If I name them differently, it’s working with a 200. Files in subdirectories css/, js/ are served properly with a status code 200.
Edit: I figured out that the problem is located in the Nginx config. If I comment out these lines, favicon.ico and robots.txt are served.
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 1
- Comments: 24 (12 by maintainers)
Also stumbled on this issue today, here is my workaround for now:
Nginx is looking for a favicon.ico file at the root level. Instead, for Laravel projects, it should look in the public folder.
Just add /public on the files paths inside your config file, and run
valet restart
:If you have run
valet secure
, you’ll find your app’s config file here:~/.config/valet/nginx/your_app.test
Otherwise, the default valet nginx config file is located here:
/usr/local/etc/nginx/valet/valet.conf
It might make more sense to edit it on a project basis, in case you don’t only serve Laravel apps with Valet.
I just wanted to comment that this still seems to be an issue as of 3.2.2.
To fix it, I modified
~/.config/valet/nginx/my-site.test
and changed:to
It seems the issue with favicon.ico / robots.txt was fixed in this commit (v2.0.5) but was later re-introduced in #819 (v2.4.1). To work around this I have removed the favicon.ico and robots.txt location blocks from my Nginx configuration.
I’m still having this issue. Just upgraded to v2.8.1 and still favicon.ico and my https://project.test/ is giving a 404 error on favicon, but opening https://project.test/favicon.ico directly does seem to work.
for anyone using Laravel Herd (which uses Valet under the hood) the nginx config files are located in
~/Library/Application Support/Herd/config
. The favicon lines in question are inherd.conf
@shengslogar Nginx doesn’t really care how you order the blocks… it has its own rules for matching priority: http://nginx.org/en/docs/http/ngx_http_core_module.html#location
@shengslogar I wonder if this is a simple order-of-operations issue? Can you try putting the unmodified favicon/robots directives before the root redirect/last directive?
Since that root-level rewrite has
last
at the end, I’m wondering if those locations are being applied after the fact?It looks like the way
serveStaticFile
works (https://github.com/laravel/valet/blob/d1967bbd0c61e528e47a79ed45556e58c2e614cf/cli/Valet/Drivers/ValetDriver.php#L137) is by doing an internal redirect to include that /some-valet-uuid-directory-path prefix.Maybe it won’t matter, but might be worth a try? Would involve not changing the “standard” way to silence favicon and robots without other weird side effects like serving the file with a 404 or NOT serving a file and still having a 200/204 response which would likely confuse people for the same reason.
I’m not convinced this is correct. The
location
context, as I understand it, is already relative to a URL (location
vsdirectory
). I think that changinglocation = /favicon.ico
tolocation = /public/favicon.ico
only “works” because you’re no longer specifying any special handling forfavicon.ico
. In other words, it’s the same thing as removing the line entirely since you don’t have anything inpublic/public/favicon.ico
directory.I’m not using valet a lot these days, but I still get notified about messages like this because I was dealing with it at one point. I did a quick google search and came up with the following:
https://stackoverflow.com/a/45562682
It occurred to me that since location is sorta “virtual,” what it’s doing is slapping some additional metadata around the location that is in addition to the actual file on disk. I have no idea why nginx is both deciding based on this that it will return a 404 and then do the work to get the actual content from disk (wat?) but maybe it makes sense? If you are adding a location context maybe the assumption is that nginx should use the location context to derive most everything about that request from the location?
I wanted to see if there was a more complex
return
directive that could be aware of whether or not the file actually exists. The best I came up with was this:https://github.com/vstoykovbg/nginx.conf-examples/blob/master/favicon.ico.md
This would look to see if the requested file exists and send a 404 only if it does not.
In short, it seems like we have a few options for how we could default this:
Assume everything is good to go and default to 200 or 204 or something
Pros
Cons
Check to see if the file exists and throw a 404 if not
Pros
Cons
Honestly, I think the last one, even though a bit “heavier”, is probably the behavior everyone expects? It’s what I expected for sure. I’d expect that we’re telling nginx that for robots.txt and favicon.ico, we know those get asked for a lot, we aren’t sure they actually exist, and we don’t want to see them in the access log, and we also don’t care if they are not there so do not bother showing me an error log about it.
I’m having the same issue.