How to fix nginx 404 not found for a Laravel app?
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
How to Fix Nginx 404 Not Found for a Laravel App: A Deep Dive into Routing Configuration
Dealing with 404 "Not Found" errors in a Laravel application when using Nginx as a reverse proxy is a common pain point. While Laravel handles routing beautifully within PHP, the web server (Nginx) must be perfectly configured to pass all dynamic requests—especially those involving subdirectories or custom routes—to the correct entry point (index.php).
As a senior developer, I can tell you that this issue rarely lies within the Laravel code itself; it almost always stems from a mismatch or misconfiguration in how Nginx is instructed to handle file requests versus PHP execution. Let's dissect your specific setup and fix this routing headache.
Understanding the Conflict: Nginx vs. Laravel Routing
Laravel relies on the public directory being served by the web server, and all dynamic routing is handled by dispatching requests through the front controller, which is typically index.php. When you see a 404 for routes like /login or custom routes like /home, it usually means Nginx is failing to correctly pass these URI paths to PHP-FPM to be processed by Laravel's router.
Your provided configuration attempts to handle specific prefixes (/mylaravel/), which is fine, but the general routing logic needs to be robust to ensure that all requests fall through to index.php.
Diagnosing Your Nginx Configuration
Let’s look at your current setup:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location /mylaravel/ {
try_files $uri $uri/ /index.php?$query_string;
}
# ... rest of the configuration
The issue often arises when specific location blocks conflict or when the general catch-all rule doesn't correctly prioritize the execution flow for all requested paths. When you access /mylaravel/login, Nginx might be trying to resolve /mylaravel/login as a static file rather than routing it through the Laravel application layer.
The Solution: Streamlining the Reverse Proxy
The most reliable way to fix this is to simplify and consolidate your location blocks, ensuring that the main entry point for all dynamic requests is correctly defined and prioritized. We want Nginx to delegate everything that doesn't match a static file directly to index.php.
Here is a revised configuration strategy tailored for a standard Laravel deployment:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost;
charset utf-8;
root /var/www/html/; # Ensure this points to your public path if necessary, or the document root.
index index.php index.html index.htm index.nginx-debian.html;
# 1. Handle all other requests by passing them through Laravel's entry point (index.php)
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# 2. Specific handling for assets (optional, but good practice)
location ~* ^.+\.(css|js|jpg|jpeg|gif|png|txt|ico|swf|xml|woff|woff2|ttf|mp3|svg|csv|xls|xlsx|eot|otf)$ {
access_log off;
expires modified +90d;
}
# 3. PHP processing block (ensure this is correctly defined)
location ~ \.php$ {
try_files $uri =404; # Use =404 if the file doesn't exist, letting Nginx handle the final failure cleanly
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; # Adjust socket path as needed
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\. {
deny all;
}
}
Key Changes Explained:
- Consolidated Root Location: The primary
location /block is now the master rule, instructing Nginx: "If it's not a static file ($uri), try serving it ($uri/), but if neither exists, execute/index.php." This single rule handles all dynamic Laravel routes seamlessly. - Removed Redundant Location: We removed the specific
location /mylaravel/block that was duplicating the logic of the main location. If your application is correctly set up in the public directory (as recommended by laravelcompany.com), this general approach handles all sub-paths (like/login) automatically because Laravel's router interprets these paths after the request hitsindex.php. - Refined PHP Location: The block handling
.phpfiles is now cleaner, focusing purely on passing the request to PHP-FPM, ensuring that failed dynamic routes result in a proper 404 handler instead of an Nginx error.
Conclusion
Fixing 404 errors for Laravel under Nginx involves moving from specific path matching to establishing a robust, generalized routing mechanism. By trusting Nginx to delegate all non-static requests to the index.php front controller, you allow Laravel's powerful routing system to handle all your /login, /home, and other dynamic routes correctly. Always ensure your web server configuration is clean and follows best practices; this approach ensures smooth operation for any application hosted on top of a robust infrastructure.