Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

orphanedrecord's avatar

Ngnix Serving 404 Instead Of 200

We have an issue where Laravel routes resolve as expected, yet do not serve the intended 200 http status code. Instead, they are serving a 404 (for content that is found). Since the pages display fine the 404s would probably not be noticeable to the end user, but the 404s are noticeable to bots and responsible web developers using dev tools and tailing the nginx access logs! Furthermore, the issue does not happen on a local Homestead environment, but on an nginx server created via Forge. Forge creates this location block:

# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/domain.com/server/*;

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

Urls without a file extension are handled correctly (issuing 200) such as domain.com/page. However, paths with file extensions, such as domain.com/page.html, result in a 404 even though the page loads fine.

We have been able apply a bandaid by defining an additional location block to match a specific page, yet, are looking for something more flexible. For example, in our server block (/etc/nginx/sites-available/mydomain.com) we can state:

location = /sitemap.xml {
    try_files $uri $uri/ /index.php?$query_string;
}

The sitemap is then issued the desired 200 http status code, but how would this work for all pages ending in .html?

For example, this does not work as expected:

location ~ \.(html)$ {
    try_files $uri $uri/ /index.php?$query_string;
}

Note, this is a Laravel app that stores pages in our database, they not flat files that exist in a directory.

Your help would be much appreciated!

0 likes
1 reply
orphanedrecord's avatar
orphanedrecord
OP
Best Answer
Level 16

This is now resolved!

As with many web dev issues we have experienced, the perceived issue is not really the issue. Check out Donald Gause's Are Your Lights On? for a better explanation.

Anyway, we had followed the HTML5 Boilerplate config and a particular location block was causing the 404 with our setup. The following was commented out:

# cache.appcache, your document html and data
# location ~* \.(?:manifest|appcache|html?|xml|json)$ {
#   expires -1;
# }

And we are back to 200. Ciao.

1 like

Please or to participate in this conversation.