tail -f /var/log/nginx/error.log
2013/05/04 23:43:35 [error] 733#0: *3662 rewrite or internal redirection cycle while internally redirecting to "/index.html", client:, server: _, request: "GET /robots.txt HTTP/1.1", host: "kowol.mysite.net"
HTTP/1.1", host: "www.joesfitness.net"
2013/05/05 00:49:14 [error] 733#0: *3783 rewrite or internal redirection cycle while internally redirecting to "/index.html", client:, server: _, request: "GET / http://www.qq.com/ HTTP/1.1", host: "www.qq.com"
2013/05/05 03:12:33 [error] 733#0: *4232 rewrite or internal redirection cycle while internally redirecting to "/index.html", client:, server: _, request: "GET / HTTP/1.1", host: "joesfitness.net"

I am getting these from nginx error log, I don't have a "kowol" sub domain, I don't have any links to qq.com or joesfitness.net on my site. Whats going on?

Edit: Nginx default config:

server {
    listen   8080; ## listen for ipv4; this line is default and implied
    listen   [::]:8080 default ipv6only=on; ## listen for ipv6

    root /usr/share/nginx/www;
    index index.php index.html index.htm;

    # Make site accessible from http://localhost/
    server_name _;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to index.html
        try_files $uri $uri/ /index.html;
        # Uncomment to enable naxsi on this location
        # include /etc/nginx/naxsi.rules

    location /doc/ {
        alias /usr/share/doc/;
        autoindex on;
        deny all;

    # Only for nginx-naxsi : process denied requests
    #location /RequestDenied {
        # For example, return an error code
        #return 418;

    #error_page 404 /404.html;

    # redirect server error pages to the static page /50x.html
    #error_page 500 502 503 504 /50x.html;
    #location = /50x.html {
    #   root /usr/share/nginx/www;

    # pass the PHP scripts to FastCGI server listening on
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

        # With php5-cgi alone:
        #With php5-fpm:
        #fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #location ~ /\.ht {
    #   deny all;

It's a strange one all right, though I'm going to bet the problem is with:

        try_files $uri $uri/ /index.html;

The problem here is that the second parameter here, $uri/, causes each of the files in your index directive to be tried in turn. If none are found, it then moves on to /index.html, which causes the same location block to be re-entered, and since it still doesn't exist, you get an endless loop.

I would rewrite this as:

        try_files $uri $uri/ =404;

to return a 404 error if none of the index files you specified in the index directive exist.

BTW, those requests you are seeing are Internet background noise. In particular, they are probes to determine whether your web server is an open proxy and can be abused to hide a malicious user's origin when he goes to perform malicious activity. Your server isn't an open proxy in this configuration, so you don't really need to worry about it.

  • Thanks for the explanation. Is there any way one could block/ban these kind of probes? – pavs-maha May 5 '13 at 5:28
  • Not really, just feed them a nice 404 and they'll figure it out eventually. – Michael Hampton May 5 '13 at 5:29
  • 2
    What's "funny" is that default config on ubuntu 13.10 has try_files $uri $uri/ /index.html; and index index.php index.html index.htm; set. resulting in the error in the question. Not so for 12.04 and 14.04, so less likely to happen on a server. – leifcr Apr 3 '14 at 8:54
  • My problem was that I'm running Laravel (with vue-router) so I needed to change /index.html to /index.php – Max Dec 17 '19 at 8:06

You will also get this error message if your index.php is entirely missing.

  • Yes, in my case I made a mistake putting the path on the root parameter. – dlopezgonzalez Apr 3 '16 at 14:41
  • index.html in my case – Beau Barker Apr 30 '20 at 14:36

This was annoying. It was working a few weeks ago, and it failed on me when I tried today.

I believed an upgrade of Ubuntu nginx package cause the default directory of where Ubuntu kept the standard index files changed, so the line:

root /usr/share/nginx/www;

Won't work anymore as the location of the files are at /usr/share/nginx/html.

To fix, one can just change the root pointer to the correct directory, or create a symlink to the new directory:

cd /usr/share/nginx
sudo ln -s html www

Works for me.


I ran into this problem yesterday because I was testing nginx over a proxy server that had cached a redirect that no longer existed. The solution for me was to $ sudo service squid3 restart on the squid3 proxy server I was connecting through.

  • Notice I shared this answer with good intentions. There are multiple reasons for this error and it takes a while to figure out the proxy caching one. – Ninjaxor May 1 '15 at 18:40

Had this error today, spend a few hours figuring the cause. Turned out someone deleted all the site's files.


Just to add another case when this happens. As in the accepted answer, in general, this happens when a sequence of locations being tried and then sort of internal redirect loop (never-ending) is created.

It sometimes manifests with bad NGINX config, and even with restrictive chmod (in some lockdown configs). Here's example.

Suppose that you have index.php front controller, as in the usual:

location / {
    try_files $uri $uri/ /index.php?$args;
location ~\.php {

You mostly serve SEO URLs like /some/thing through your index.php.

But as usual, there are some PHP files that you need to be exposed directly (thus the location ~\.php and not location = /index.php.

Also suppose that your index.php was chmod-ded to 0400 for security lockdown.

Everything still works fine in this case, as long as the file is owned by the "PHP-FPM user". NGINX does not need to read the file, because it merely passes its filename to PHP-FPM for execution and gets back the FastCGI response.

Then you want to handle a case of what happens when someone visits /non-existent.php because with this rather standard config you would get No input file specified. for that case.

To deal with this, some folks add:

if (!-e $request_filename) { rewrite / /index.php last; } ## Catch 404s that try_files miss

Well, of course if is evil as per nginx, but that's not about it. Everything will now break with the redirection cycle error. Why?

Because this sequence happens in a loop:

  • When /some/page URL is requested, nginx enters location /, doesn't find a real file and turns it to /index.php
  • It then enters .php location block and tries to check if it can read index.php. Since it can't, it rewrites it to the same index.php then arrives back to .php again.
  • Thank you, Danila Vershinin! This helped for me: location / { try_files $uri $uri/ /index.php?$args; } – Brabus Sep 6 '19 at 20:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.