# Nginx 404 Not Found for Static Files and Routes
You deploy a site and Nginx returns 404 Not Found, either for static assets or for routes that should be rewritten into your app entrypoint. The files often exist on disk, but Nginx is looking in the wrong place, matching the wrong location block, or sending the request through the wrong try_files path.
Introduction
A 404 Not Found means Nginx couldn't locate the requested resource at the path it computed. The file exists somewhere - just not where Nginx is looking.
Check the error log:
tail -f /var/log/nginx/error.logYou'll see entries like:
2026/04/04 11:20:30 [error] 5678#5678: *10 open() "/var/www/html/css/styles.css" failed (2: No such file or directory), client: 192.168.1.50, server: example.com, request: "GET /css/styles.css HTTP/1.1"The log tells you exactly where Nginx looked. Compare that path to where your file actually exists.
Symptoms
Common error messages include:
tail -f /var/log/nginx/error.log2026/04/04 11:20:30 [error] 5678#5678: *10 open() "/var/www/html/css/styles.css" failed (2: No such file or directory), client: 192.168.1.50, server: example.com, request: "GET /css/styles.css HTTP/1.1"```nginx server { listen 80; server_name example.com;
# Wrong: Nginx looks for /var/www/html/css/styles.css root /var/www/html;
location /css/ { # This inherits root from server block # Final path: /var/www/html/css/styles.css } } ```
Common Causes
- Configuration misconfiguration
- Missing or incorrect credentials
- Network connectivity issues
- Version compatibility problems
- Resource exhaustion or limits
- Permission or access denied
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Common Cause 1: Wrong Root Directive
The root directive appends the request URI to the specified path. This is the most common source of path confusion.
Problematic config: ```nginx server { listen 80; server_name example.com;
# Wrong: Nginx looks for /var/www/html/css/styles.css root /var/www/html;
location /css/ { # This inherits root from server block # Final path: /var/www/html/css/styles.css } } ```
But your files are actually at /var/www/myapp/static/css/styles.css.
Solution: ```nginx server { listen 80; server_name example.com;
root /var/www/myapp/static;
location /css/ { # Now looks at /var/www/myapp/static/css/styles.css } } ```
Or use different roots for different locations: ```nginx server { listen 80; server_name example.com;
location /static/ { root /var/www/myapp; # Looks at /var/www/myapp/static/ }
location /assets/ { root /var/www/uploads; # Looks at /var/www/uploads/assets/ } } ```
Common Cause 2: Root vs Alias Confusion
The alias directive works differently from root. This trips up many configurations.
With root:
``nginx
location /images/ {
root /var/www/data;
# Request: GET /images/logo.png
# Looks for: /var/www/data/images/logo.png
}
With alias:
``nginx
location /images/ {
alias /var/www/data/;
# Request: GET /images/logo.png
# Looks for: /var/www/data/logo.png (NOT /var/www/data/images/)
}
The trailing slash matters with alias:
```nginx # These are equivalent: location /images { alias /var/www/data; # No trailing slash on either }
location /images/ { alias /var/www/data/; # Trailing slash on both }
# This causes problems: location /images/ { alias /var/www/data; # Trailing slash mismatch # Request: GET /images/logo.png # May look for: /var/www/datalogo.png (concatenated!) } ```
Best practice - be consistent:
``nginx
location /images/ {
alias /var/www/data/images/;
}
Common Cause 3: Try Files Misconfiguration
The try_files directive checks files in order and serves the first match. If none match, it returns 404.
Problematic config:
``nginx
location / {
try_files $uri $uri/ =404;
# This returns 404 if file doesn't exist and it's not a directory
}
For single-page applications, you typically want:
``nginx
location / {
root /var/www/myapp;
try_files $uri $uri/ /index.html;
# Falls back to index.html for client-side routing
}
Diagnosis: ```bash # Test if the file exists at the path Nginx computed ls -la /var/www/html/css/styles.css
# Check Nginx's internal path resolution sudo nginx -T 2>/dev/null | grep -A 10 "location /css" ```
Common Cause 4: Incorrect Location Matching
Location block precedence can cause unexpected behavior.
- 1.Location matching order:
- 2.Exact match:
location = /path - 3.Priority prefix:
location ^~ /path - 4.Regex (in order):
location ~ /pathorlocation ~* /path - 5.Prefix (longest match):
location /path
Problematic config: ```nginx # This regex matches first for /css/styles.css location ~* \.css$ { root /var/www/old; }
# This never gets matched location /css/ { root /var/www/new; } ```
Solution: ```nginx # Use priority prefix for static files location ^~ /css/ { root /var/www/new; }
# Or use exact regex ordering location ~* ^/css/.*\.css$ { root /var/www/new; } ```
Common Cause 5: Case Sensitivity Issues
On Linux, filenames are case-sensitive. Styles.css and styles.css are different files.
Diagnosis: ```bash # Check actual filename case ls -la /var/www/html/css/
# Compare with what's requested grep "GET /css/" /var/log/nginx/access.log ```
Solution:
Either rename files to match requests, or handle case-insensitivity:
``nginx
# Case-insensitive matching for file extensions
location ~* \.(css|js|png|jpg|gif)$ {
root /var/www/html;
}
Common Cause 6: Symbolic Link Issues
Nginx may not follow symbolic links depending on configuration.
Diagnosis: ```bash # Check if path contains symlinks ls -la /var/www/html/
# Check symlink target readlink -f /var/www/html/css ```
Solution: ```nginx # Enable following symlinks (default) location /css/ { root /var/www/html; disable_symlinks off; # Follows symlinks }
# Disable for security in some cases location /uploads/ { root /var/www/html; disable_symlinks on; # Won't follow symlinks } ```
Common Cause 7: Hidden Files
Files starting with . are hidden and may not be served.
Diagnosis:
``bash
ls -la /var/www/html/
Solution:
Nginx serves hidden files by default, but check for explicit blocks:
``nginx
# This would block hidden files
location ~ /\. {
deny all;
}
Verification
- 1.Identify where Nginx is looking:
- 2.```bash
- 3.# Watch error log while making request
- 4.tail -f /var/log/nginx/error.log &
- 5.curl http://localhost/css/styles.css
- 6.
` - 7.Verify file exists at that path:
- 8.```bash
- 9.ls -la /var/www/html/css/styles.css
- 10.
` - 11.Test configuration:
- 12.```bash
- 13.sudo nginx -t
- 14.
` - 15.Debug with full configuration dump:
- 16.```bash
- 17.sudo nginx -T | less
- 18.
` - 19.Test location matching:
- 20.```bash
- 21.# Install nginx debug tools or use curl with verbose
- 22.curl -v http://localhost/css/styles.css
- 23.
`
Verification
| Symptom | Cause | Fix |
|---|---|---|
| Path wrong in error log | root directive issue | Adjust root path |
| Works with alias, not root | root vs alias difference | Use correct directive |
| SPA routes return 404 | try_files missing fallback | Add /index.html fallback |
| Regex location ignored | Wrong precedence | Use ^~ or reorder |
| File exists but 404 | Case sensitivity | Match case or use ~* |
| Symlinks return 404 | disable_symlinks on | Change to off |
The key to solving 404 errors is reading the error log. It tells you exactly where Nginx looked. Then verify: does the file exist at that path?
Related Articles
- [Nginx troubleshooting: Fix Lambda Permission Denied - Complete ](fix-lambda-permission-denied)
- [Nginx web server troubleshooting: Fix Client Max Body Size Large Upload Nginx Issue ](client-max-body-size-large-upload-nginx)
- [Fix Apache 502 Proxy Error](fix-apache-502-proxy-error)
- [Fix Apache LogLevel Core Debug Configuration](fix-apache-loglevel-core-debug)
- [Fix Cloudflare 502 Bad Gateway Error](fix-cloudflare-502-bad-gateway)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "How to Fix Nginx 404 Not Found Errors for Static Files and Routes", "description": "Resolve Nginx 404 Not Found errors by checking static file paths, root vs alias, location matching, and try_files route fallback configuration.", "url": "https://www.fixwikihub.com/fix-nginx-404-not-found", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-27T19:09:19.201Z", "dateModified": "2025-11-27T19:09:19.201Z" } </script>