Knowledge
nginx rewrite or internal redirection cycle
#Nginx
This error means nginx kept redirecting a request back to itself until it gave up. Almost always a try_files directive that loops, producing a 500 error.
Published by Mark van Eijk on June 23, 2026 · 1 minute read
- About the error
- Why do I see this error
- Solution
- Use the standard Laravel/PHP try_files
- Check the root actually contains index.php
About the error
The page returns a 500 and the nginx error log shows:
rewrite or internal redirection cycle while internally redirecting to "/index.php"
nginx tried to resolve a request, that resolution pointed at another location, which pointed back, and so on. After 10 internal redirects nginx assumes a loop and aborts with a 500.
Why do I see this error
The classic cause is a try_files that, when nothing matches, falls back to a target that itself triggers the same try_files again. For a PHP app it usually means:
- The fallback file (
index.php) doesn't exist at the expected path, so the fallback re-enters the same block. - The
rootis wrong, so nginx never finds the real file and keeps redirecting. - A
try_filespointing at a named location or URI that loops back.
Solution
Use the standard Laravel/PHP try_files
A correct front-controller setup looks like this. Note the $uri and $uri/ are tried first, and the final fallback passes the path as a query string rather than re-requesting a file:
server {
root /var/www/html/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
}
}
Check the root actually contains index.php
The most common real cause is a wrong root. If /var/www/html/public/index.php doesn't exist, the fallback can never resolve and loops:
ls -l /var/www/html/public/index.php
Point root at the directory that genuinely contains the front controller (for Laravel that's public, not the project root).
Validate and reload after fixing:
nginx -t && systemctl reload nginx
For a deeper look at how try_files resolves requests, see the nginx try_files article. A redirect loop that happens in the browser rather than inside nginx shows up as ERR_TOO_MANY_REDIRECTS instead.
Subscribe to our newsletter
Do you want to receive regular updates with fresh and exclusive content to learn more about web development, hosting, security and performance? Subscribe now!