# 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:

bash
tail -f /var/log/nginx/error.log

You'll see entries like:

bash
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:

bash
tail -f /var/log/nginx/error.log
bash
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"

```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. 1.Check logs for specific error messages
  2. 2.Verify configuration settings
  3. 3.Test network connectivity
  4. 4.Review recent changes
  5. 5.Apply corrective action
  6. 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. 1.Location matching order:
  2. 2.Exact match: location = /path
  3. 3.Priority prefix: location ^~ /path
  4. 4.Regex (in order): location ~ /path or location ~* /path
  5. 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; }

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. 1.Identify where Nginx is looking:
  2. 2.```bash
  3. 3.# Watch error log while making request
  4. 4.tail -f /var/log/nginx/error.log &
  5. 5.curl http://localhost/css/styles.css
  6. 6.`
  7. 7.Verify file exists at that path:
  8. 8.```bash
  9. 9.ls -la /var/www/html/css/styles.css
  10. 10.`
  11. 11.Test configuration:
  12. 12.```bash
  13. 13.sudo nginx -t
  14. 14.`
  15. 15.Debug with full configuration dump:
  16. 16.```bash
  17. 17.sudo nginx -T | less
  18. 18.`
  19. 19.Test location matching:
  20. 20.```bash
  21. 21.# Install nginx debug tools or use curl with verbose
  22. 22.curl -v http://localhost/css/styles.css
  23. 23.`

Verification

SymptomCauseFix
Path wrong in error logroot directive issueAdjust root path
Works with alias, not rootroot vs alias differenceUse correct directive
SPA routes return 404try_files missing fallbackAdd /index.html fallback
Regex location ignoredWrong precedenceUse ^~ or reorder
File exists but 404Case sensitivityMatch case or use ~*
Symlinks return 404disable_symlinks onChange 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?

  • [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>