Nginx 1.2.2 try_files Configuration: Fixing Internal Redirection Cycle Error


2 views

After updating to Nginx 1.2.2, you might encounter a 500 Internal Server Error when using try_files with this common pattern:

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

The error log shows:

2012/08/13 09:20:29 [error] 18457#0: *60 rewrite or internal redirection cycle 
while internally redirecting to "/index.html"

This behavior occurs because Nginx 1.2.2 introduced stricter handling of internal redirections. When the requested file doesn't exist, Nginx tries to serve /index.html, but if this file isn't found either, it creates an infinite loop.

Here's the proper way to configure try_files in Nginx 1.2.2+:

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

Key improvements:

  • Added $uri/ to check for directory existence
  • Added =404 fallback to prevent cycles
  • Explicit handling of missing files

Here's a full server block configuration that works correctly:

server {
    root /var/www/example.com;
    index index.html;
    
    location / {
        try_files $uri $uri/ /index.html;
        
        # Additional security headers
        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-Content-Type-Options "nosniff";
    }
    
    # Handle 404 errors properly
    error_page 404 /404.html;
    location = /404.html {
        internal;
    }
}

If you're still experiencing issues:

  1. Enable debug logging in nginx.conf:
    error_log /var/log/nginx/error.log debug;
    
  2. Verify file permissions:
    chmod -R 755 /path/to/your/root
    chown -R www-data:www-data /path/to/your/root
    
  3. Check for symlink issues in your document root

For Single Page Applications (SPAs), use this enhanced version:

location / {
    try_files $uri $uri/ @rewrites;
}

location @rewrites {
    rewrite ^(.+)$ /index.html last;
}

location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
    expires max;
    add_header Cache-Control "public";
}

After upgrading to Nginx 1.2.2, many developers encounter a frustrating issue where the try_files directive results in a 500 Internal Server Error with the message "rewrite or internal redirection cycle".

The problematic configuration typically looks like this:

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

While this worked in earlier versions, Nginx 1.2.2 handles URI resolution differently, leading to potential redirection loops.

The error log reveals the core issue:

2012/08/13 09:20:29 [error] 18457#0: *60 rewrite or internal redirection cycle 
while internally redirecting to "/index.html"

Here are three working approaches:

1. Complete try_files Syntax

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

2. Absolute Path Resolution

location / {
    try_files $uri $uri/ $document_root/index.html;
}

3. Using named locations

location / {
    try_files $uri $uri/ @fallback;
}

location @fallback {
    root /usr/share/nginx/mysite.com/public_html;
    try_files /index.html =404;
}

When implementing these solutions:

  • Ensure your root directive is properly set
  • Verify file permissions in your document root
  • Check for conflicting rewrite rules
  • Consider using absolute paths for better reliability

Remember that Nginx processes try_files directives in order, and the last parameter should always be a guaranteed endpoint (either a file or a named location).