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:
- Enable debug logging in nginx.conf:
error_log /var/log/nginx/error.log debug;
- Verify file permissions:
chmod -R 755 /path/to/your/root chown -R www-data:www-data /path/to/your/root
- 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).