एरर समाधान · सर्वर एरर

nginx "rewrite or internal redirection cycle" (500) Fix

Fix nginx 500 errors logged as rewrite or internal redirection cycle by finding the try_files, rewrite or error_page rule that keeps sending requests back to itself.

Error messagerewrite or internal redirection cycle while internally redirecting to "/index.html

लेखक: SiteDownCheck संपादकीय टीम · अपडेट: अक्टूबर 14, 2026 · 3 मिनट पढ़ने में

Visitors see "500 Internal Server Error", and the nginx error log says:

[error] 901#901: *14 rewrite or internal redirection cycle while internally redirecting to "/index.html", client: 203.0.113.9, server: example.com, request: "GET /about HTTP/1.1", host: "example.com"

nginx processes some config rules by redirecting a request internally: try_files fallbacks, rewrite ... last, error_page with a URI and index handling. The browser never sees these jumps. To protect itself from loops, nginx stops after 10 internal redirects and returns 500. This error is different from a browser redirect loop; if the browser says too many redirects, read ERR_TOO_MANY_REDIRECTS.

The URI named at the end of the log line is the one that kept being re-entered. That is your starting point.

The most common cause: try_files fallback does not exist

server {
    root /var/www/app/dist;
    location / {
        try_files $uri $uri/ /index.html;
    }
}

This looks right, but if /var/www/app/dist/index.html does not exist, nginx jumps to /index.html, matches location / again, tries $uri (missing), then jumps to /index.html again, and so on until it hits the limit. The fix is not in the config syntax; it is that the file is missing or root is wrong.

ls -l /var/www/app/dist/index.html
sudo nginx -T | grep -n -E "root|try_files"

Check that root is the folder containing the file, that the build step produced it, and that the file name matches case exactly. Give the fallback file its own location so a missing file ends in a normal 404 instead of a loop:

location / {
    try_files $uri $uri/ /index.html;
}
location = /index.html {
    try_files $uri =404;
}

Now a missing index.html ends in a normal 404 and the log shows open() ... failed (2: No such file or directory).

Cause 2: rewrite rules that match their own output

rewrite ^/(.*)$ /index.php?q=$1 last;

With last, nginx restarts location matching with the new URI. If the same rule matches the new URI, it loops. Exclude the target or use a more specific pattern:

rewrite ^/(?!index\.php)(.*)$ /index.php?q=$1 last;

Better, replace pattern rewrites with try_files where possible. Test regular expressions beforehand; PCRE behavior in nginx is the same as in most tools.

Cause 3: PHP front controllers and containers

A WordPress or Laravel site with try_files $uri $uri/ /index.php?$args; loops the same way when index.php is not under root. The usual real-world triggers are a Docker volume mounted over the web root that hid the files, a deploy that switched symlinks to an empty release folder, or a root that points one directory too high or too low. Check what is actually on disk, not what the deploy script intended.

Debugging technique

Temporarily enable debug logging for one client only (this requires an nginx built with --with-debug, as most distribution packages are):

error_log /var/log/nginx/debug.log debug;
events { debug_connection 203.0.113.9; }

The debug log prints each location match and rewrite step. Remove it afterward since it is very verbose. Also check nginx -t for syntax, and reload with sudo systemctl reload nginx.

How to verify

Request the URL that failed, plus the home page and an asset, and check the response with the HTTP स्टेटस चेकर. A correct setup returns 200 for pages and 404 for really missing paths, never 500. The रीडायरेक्ट चेकर will show that no external redirects are involved. Put an अपटाइम मॉनिटर on a deep link as well as the home page, because SPA routing bugs often only break non-root paths.

अगले कदम

सामान्य प्रश्न

How many internal redirects does nginx allow?

Ten. After that it stops processing and returns a 500 with this log message.

Is this the same as a redirect loop in the browser?

No. Internal redirects are invisible to the client and happen entirely inside nginx. The browser only sees the final 500.

Why does it only happen on some URLs?

Only URLs that fall through to the failing fallback or match the self-referencing rewrite trigger it. Your home page may match a different path.

Can a missing file really cause a loop?

Yes. A try_files fallback to a nonexistent file re-enters the same location block repeatedly until the limit is reached.

Get notified when this fix updates

Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.

यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.