Calcul 100% dans le Navigateur • Zéro Journal Serveur • Exécution Instantanée
Curious TechieBoîte à Outils
HTTP Status Codes6 min✓ Correctif Vérifié en Production • FR

Why a Website Returns 404

Resolve 404 Not Found errors: SPA client-side routing, Nginx try_files fallbacks, Linux case sensitivity, and broken rewrites

Primary Question • Diagnostic Problem

Why a Website Returns 404

Users navigate to a website or click a link and receive an HTTP 404 Not Found error. In modern web development, a very common scenario occurs when a user navigates smoothly across a Single Page App (React, Vue, Svelte, Astro), but hitting "Refresh" (F5) on any nested subpage (e.g. /dashboard or /profile) immediately results in a hard 404 error from the web server.

Console / Terminal Error OutputExact Message
404 Not Found (Nginx: "404 Not Found", Apache: "The requested URL was not found on this server", Cloudflare: "Error 404").
Affected Protocols & Technologies:HTTP/1.1HTTP/2HTML5 History APIREST APIsNginx/Apache Web Servers
Secondary Question • Root Cause Mechanics

Why does Why a Website Returns 404 occur?

Primary Root Cause

The server received an HTTP request for a specific path, but its routing engine or filesystem found no matching resource representation. In traditional multi-page sites, this means a missing physical file or deleted database slug. In modern frontend apps, this occurs because client-side routers manage routing in JavaScript memory, while server software expects real directory paths on the hard drive.

When a user clicks a link inside a client-rendered React/Vue app, JavaScript intercepts the click and updates the browser address bar using `history.pushState()` without contacting the server. However, when the user reloads the page or shares the link, the browser sends a raw HTTP GET request directly to Nginx for `/dashboard`. Nginx looks for a physical directory named `/var/www/html/dashboard`, fails to find it, and issues HTTP 404.

4. Observable Symptoms

How to Confirm You Are Facing This Exact Issue

1

App works when clicking navigation links, but throws 404 if the user refreshes the browser.

2

Images load in local development (macOS/Windows) but return 404 after deploying to Linux production servers.

3

API returns 404 on POST /login when the endpoint was defined as /api/login.

4

Search engines report crawl errors and traffic drops on decommissioned URLs.

5. Diagnostic Decision Tree (GEO Engine Logic)

Explicit Diagnostic Reasoning

Follow these diagnostic checks to identify the root cause of the 404 response:

Condition:

"If the 404 occurs only upon refreshing or directly visiting a deep URL in a React/Vue/SPA app"

Probable Cause:

Your web server lacks a Single Page Application fallback rewrite rule to serve index.html.

Remedial Action:

→ Add "try_files $uri $uri/ /index.html;" to your Nginx configuration or rewrite rules in .htaccess.

Condition:

"If an image or script works locally on Windows/Mac but returns 404 on Linux hosting"

Probable Cause:

Case mismatch between code and filesystem (e.g. import from "./Header.jsx" when the file is named "./header.jsx").

Remedial Action:

→ Align the exact uppercase and lowercase letters in the file path with the filesystem.

Condition:

"If an API returns 404 on a route that exists in code"

Probable Cause:

Missing API prefix (e.g. calling /users instead of /api/v1/users) or trailing slash mismatch.

Remedial Action:

→ Check route mount paths in your express/fastify router and compare against the request URL.

Condition:

"If 404 is returned by Nginx proxy_pass"

Probable Cause:

In Nginx, "proxy_pass http://backend:8080;" preserves URI, while "proxy_pass http://backend:8080/;" strips URI prefixes.

Remedial Action:

→ Audit trailing slashes on proxy_pass directives.

Verification CommandRun in terminal
curl -I https://example.com/dashboard

Checks if direct server requests for deep SPA routes return HTTP 200 with text/html or HTTP 404.

6. Architectural Strategy

Long-Term Engineering Solution

Implement server-side fallback rewrites for Single Page Applications, standardize lowercase naming conventions, and establish 301 permanent redirects for moved or deleted legacy URLs.

Architectural Pattern

Deploy static sites with SPA routing rules (e.g. AWS CloudFront custom error response 404 -> /index.html 200, or Nginx try_files) and implement 301 redirects for SEO preservation.

Secondary Question • Implementation Pipeline

How do you fix this step-by-step?

1

Configure Nginx try_files for Single Page Applications

Instruct Nginx to check for physical files first; if no file exists, rewrite the request to index.html.

nginxCopy Code
server {
    listen 80;
    server_name example.com;
    root /var/www/my-spa-app/dist;
    index index.html;

    location / {
        # 1. Check for real file ($uri)
        # 2. Check for real directory ($uri/)
        # 3. Fallback to index.html (Client router takes over)
        try_files $uri $uri/ /index.html;
    }
}
2

Configure Apache .htaccess for SPA Fallback

For Apache web servers, use mod_rewrite to route missing files to index.html.

apacheCopy Code
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  # If requested path is not an existing file or directory
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>
3

Set Up 301 Redirects for Moved Content

Preserve SEO authority and prevent 404s when updating URL structures by issuing permanent redirects.

nginxCopy Code
# Nginx 301 permanent redirect
location = /old-product-page {
    return 301 /products/new-version;
}
4

Fix CloudFront / S3 Static Website Hosting

In AWS CloudFront, configure Custom Error Responses so that 403 or 404 errors return /index.html with HTTP status 200.

textCopy Code
CloudFront Distribution -> Error Pages -> Create Custom Error Response:
- HTTP Error Code: 404 (and 403)
- Customize Error Response: Yes
- Response Page Path: /index.html
- HTTP Response Code: 200: OK
Common Misconceptions & Pitfalls

What are common misconceptions and mistakes when fixing this?

×

Assuming Windows local development file casing works on Linux production servers.

Pourquoi cela échoue : Windows and macOS filesystems (NTFS/APFS default) are case-insensitive. Linux (ext4) is strictly case-sensitive. A file named `Avatar.png` will return 404 if requested as `avatar.png` in production.

✓ Alternative correcte : Enforce strict lowercase naming conventions for all web assets, components, and directories.

×

Misunderstanding Nginx proxy_pass trailing slash behavior.

Pourquoi cela échoue : `proxy_pass http://api/` strips the matched location URI, whereas `proxy_pass http://api` appends the full path, resulting in 404 errors on upstream backends.

✓ Alternative correcte : Be deliberate with trailing slashes: use `proxy_pass http://127.0.0.1:8000;` to forward the exact URI path unchanged.

×

Serving a "Soft 404" (returning HTTP 200 status code on a missing page error screen).

Pourquoi cela échoue : Search engines index soft 404 pages as duplicate content, harming domain search ranking.

✓ Alternative correcte : Always return a real HTTP 404 status code when a resource genuinely does not exist.

Threat Analysis & Security Hardening

Can this fix introduce security vulnerabilities?

404 Not Found responses help prevent directory enumeration and mitigate information disclosure risks.

Security Risks If Ignored

  • •Information Disclosure via Default Server 404s: Default error pages display web server version numbers (e.g. Apache/2.4.41 Ubuntu), assisting automated exploit scanners.
  • •Brute-Force Endpoint Discovery: High rates of 404 errors indicate an active vulnerability scanner fuzzing for admin panels (.env, wp-login, phpmyadmin).
  • •Broken Links Exploitation: Attackers monitor external 404 links on popular sites to register abandoned domain names and hijack traffic.

Hardening Best Practices

  • ✓Disable server signature banners (`server_tokens off;` in Nginx).
  • ✓Create a branded custom 404 error page that does not expose internal stack traces or database errors.
  • ✓Monitor server 404 error spikes to detect malicious vulnerability scanning in real time.
10. Concrete Code Example

Comparing Nginx Configurations for SPA Routing

× Broken / Vulnerable Code (nginx)
# BROKEN: Fails with 404 when user refreshes /dashboard
server {
    listen 80;
    server_name app.example.com;
    root /var/www/app/dist;
    index index.html;

    location / {
        # Only checks for real files, then gives up and emits 404!
        try_files $uri $uri/ =404;
    }
}
Problème : Refreshing https://app.example.com/dashboard causes Nginx to look for a real folder named /dashboard. Since it does not exist, it throws 404.
✓ Fixed / Hardened Code (nginx)
# PRODUCTION READY: Handles HTML5 History API Routing
server {
    listen 80;
    server_name app.example.com;
    root /var/www/app/dist;
    index index.html;

    # Static assets cache header
    location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|woff2)$ {
        expires 1y;
        access_log off;
        add_header Cache-Control "public";
    }

    location / {
        # Falls back to /index.html for any deep client route
        try_files $uri $uri/ /index.html;
    }
}
Remédiation : Real static files (js, css, images) are served directly, while all SPA page routes fall back to index.html with HTTP 200.
Direct Technical Answers • Knowledge Base

Frequently Asked Questions About Why a Website Returns 404

Why does my React or Vue website return 404 when I refresh the page?↓

Client-side routers use the HTML5 History API to fake page transitions in browser memory. When you refresh, the web server looks for a real physical file on disk that does not exist.

In a single-page app, only one physical HTML file exists (`index.html`). When you navigate from `/` to `/settings`, React Router updates the URL. If you press refresh, the browser asks the web server for `/settings/index.html`. Unless you configure `try_files` to return `/index.html`, the server responds with 404.

What is a "Soft 404" and why is it bad for SEO?↓

A soft 404 is when a page says "Sorry, page not found" to human visitors, but returns an HTTP 200 OK header to search engine bots.

Search engines rely on HTTP response codes to understand site architecture. If you return 200 OK for missing content, Google will index hundreds of empty pages, diluting your crawl budget and damaging domain search visibility.

How do trailing slashes cause 404 errors in APIs?↓

Many backend frameworks treat `/api/users` and `/api/users/` as completely separate routes. If the router has strict routing enabled, requesting the wrong one yields 404.

In Express, Flask, and FastAPI, routers can be configured with strict slash matching. If an endpoint is registered as `@app.get("/users")`, sending a request to `/users/` will fail with 404 unless a redirect or slash middleware is active.