Fixing Nginx 500 Error: Internal Redirection Cycle (SPA vs PHP Config)
Content
## Symptom
When configuring Nginx, accessing the website returns a `500 Internal Server Error`. Checking the Nginx error log reveals the following message:
```text
2026/04/19 00:07:24 [error] 63#63: *33643 rewrite or internal redirection cycle while internally redirecting to "/index.html", client: 114.x.x.x, server: wiki.lib00.com, request: "GET / HTTP/2.0", host: "wiki.lib00.com"
```
This is a classic Nginx **Internal Redirection Cycle** error.
---
## Root Cause Analysis
Nginx has entered an infinite loop while processing the request. This usually happens when the `try_files` directive is configured as a fallback mechanism for frontend routing, but the fallback file (e.g., `/index.html`) does not exist on the disk. This causes Nginx to repeatedly trigger the redirection logic until it hits the built-in limit of 10 times, resulting in a 500 error.
**Specific Scenario in this Case**: During deployment, DP@lib00 directly copied an old Nginx configuration from a Single Page Application (SPA, like React/Vue) to run a **PHP-rendered project**. SPA projects rely on `index.html` as the entry point, whereas PHP projects rely on `index.php`. Since there was no `index.html` in the project directory, Nginx fell into an infinite loop searching for the entry file.
---
## Wrong vs. Correct Configuration
### 1. Wrong Configuration (For SPA, NOT for PHP)
Applying an SPA config directly causes Nginx to loop because it cannot find `index.html`.
```nginx
# WRONG: Using SPA config for a PHP project
root /var/www/wiki.lib00.com/app_root;
location / {
# If file or directory is not found, fallback to /index.html
try_files $uri $uri/ /index.html;
}
```
### 2. Correct Configuration (For PHP Projects)
For a PHP project, you need to rewrite unfound requests to `index.php` and configure FastCGI to process the PHP scripts.
```nginx
# CORRECT: PHP Project Configuration
root /var/www/wiki.lib00.com/php_app/public;
location / {
# If the requested file does not exist, rewrite to index.php
if (!-e $request_filename){
rewrite ^/(.*)$ /index.php?s=/$1 last;
}
index index.php;
}
# PHP FastCGI Configuration
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000; # Adjust PHP-FPM address as needed
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
include fastcgi_params;
}
```
---
## Extended Troubleshooting Tips
If you are actually deploying an SPA project (like Vue/React) and encounter this error, check the following:
1. **File Existence**: Verify if `index.html` actually exists in the path specified by the `root` directive (e.g., `/var/www/lib00/dist/`).
2. **Path Configuration**: Ensure the `root` or `alias` points to the absolute path of your frontend build artifacts and is spelled correctly.
3. **Permissions**: The file might exist, but the Nginx user (e.g., `www-data` or `nginx`) lacks read permissions for the file or execute permissions for the directory. Run `ls -l` to check.
4. **Debugging Trick**: Temporarily change `try_files $uri $uri/ /index.html;` to `try_files $uri $uri/ =404;`. If accessing the site returns a 404, it confirms a missing file or wrong path. If it returns a 403, it's a permission issue.
Related Contents
Stop Making Timezone Mistakes in PHP: The Ultimate Guide to time() and UTC
Duration: 00:00 | DP | 2026-06-25 11:29:00Beyond 99.9%: A Deep Dive into a User-Centric Weighted Sampling Algorithm for Availability
Duration: 00:00 | DP | 2026-06-26 12:57:00PHP Log Aggregation Performance Tuning: Database vs. Application Layer - The Ultimate Showdown for Millions of Records
Duration: 00:00 | DP | 2026-01-06 08:05:09MySQL TIMESTAMP vs. DATETIME: The Ultimate Showdown on Time Zones, UTC, and Storage
Duration: 00:00 | DP | 2025-12-02 08:31:40The Ultimate 'Connection Refused' Guide: A PHP PDO & Docker Debugging Saga of a Forgotten Port
Duration: 00:00 | DP | 2025-12-03 09:03:20How Can a Docker Container Access the Mac Host? The Ultimate Guide to Connecting to Nginx
Duration: 00:00 | DP | 2025-12-08 23:57:30Nginx vs. Vite: The Smart Way to Handle Asset Path Prefixes in SPAs
Duration: 00:00 | DP | 2025-12-11 13:16:40The Ultimate PHP Guide: How to Correctly Handle and Store Markdown Line Breaks from a Textarea
Duration: 00:00 | DP | 2025-11-20 08:08:00Stop Mixing Code and User Uploads! The Ultimate Guide to a Secure and Scalable PHP MVC Project Structure
Duration: 00:00 | DP | 2026-01-13 08:14:11The Ultimate Guide: Solving Google's 'HTTPS Invalid Certificate' Ghost Error When Local Tests Pass
Duration: 00:00 | DP | 2025-11-29 08:08:00How Do You Pronounce Nginx? The Official Guide to Saying It Right: 'engine x'
Duration: 00:00 | DP | 2025-11-30 08:08:00Mastering PHP: How to Elegantly Filter an Array by Keys Using Values from Another Array
Duration: 00:00 | DP | 2026-01-14 08:15:29Stop Manual Debugging: A Practical Guide to Automated Testing in PHP MVC & CRUD Applications
Duration: 00:00 | DP | 2025-11-16 16:32:33Mastering PHP Switch: How to Handle Multiple Conditions for a Single Case
Duration: 00:00 | DP | 2025-11-17 09:35:40`self::` vs. `static::` in PHP: A Deep Dive into Late Static Binding
Duration: 00:00 | DP | 2025-11-18 02:38:48PHP String Magic: Why `{static::$table}` Fails and 3 Ways to Fix It (Plus Security Tips)
Duration: 00:00 | DP | 2025-11-18 11:10:21Can SHA256 Be "Decrypted"? A Deep Dive into Hash Function Determinism and One-Way Properties
Duration: 00:00 | DP | 2025-11-19 04:13:29The Magic of PHP Enums: Elegantly Convert an Enum to a Key-Value Array with One Line of Code
Duration: 00:00 | DP | 2025-12-16 03:39:10Recommended
Are Your PHP Prefixes Truly Unique? A Deep Dive into Collision Probability from `mt_rand` to `random_bytes`
00:00 | 102Generating unique identifiers in PHP is a common t...
Composer Script Not Running? Unveiling the `post-install-cmd` Trap and the Ultimate Solution
00:00 | 103Have you ever run `composer install` only to find ...
Bootstrap Pro Tip: How to Gracefully Strip and Customize Anchor `<a>` Tag Styles
00:00 | 142Annoyed by the default underline and blue color of...
Show Hidden Files on Mac: The Ultimate Guide (2 Easy Methods)
00:00 | 129Struggling to find hidden files like .gitconfig or...