nginx: [emerg] "try_files" directive "duplicate default parameter" in /etc/nginx/conf.d/mysite.conf:12
Your current configuration attempts to serve both the directory and index.html file simultaneously, which creates ambiguity. The 500 error occurs because nginx can't properly resolve the request path when both $uri/
and $uri/index.html
are specified in try_files.
Here's the improved configuration that properly handles both HTML extension removal and clean URL rewriting:
server {
listen 80;
server_name mysite.com;
root /var/www/mysite/public;
location / {
try_files $uri $uri.html $uri/index.html =404;
}
location /media/ {
alias /var/www/mysite/public/media/;
error_page 404 = /404;
expires 30d;
}
location /static/ {
alias /var/www/mysite/public/static/;
error_page 404 = /404;
expires 30d;
}
}
The revised configuration makes several important changes:
- Moved root directive outside location blocks for cleaner configuration
- Modified try_files order to properly check for both .html files and directory indexes
- Added proper error handling with =404 fallback
Here's how different URLs will now resolve:
http://mysite.com/ → /var/www/mysite/public/index.html
http://mysite.com/post/13considerations → /var/www/mysite/public/post/13considerations.html
http://mysite.com/post/13considerations/ → /var/www/mysite/public/post/13considerations/index.html
For more complex scenarios where you might have both HTML and non-HTML files:
location / {
try_files $uri $uri/ @htmlext;
}
location @htmlext {
if (-f "${document_root}${uri}.html") {
rewrite ^(.*)$ $1.html break;
}
try_files $uri $uri/ =404;
}
This configuration first checks for the exact file, then directory, then falls back to checking for .html extension before finally returning 404 if nothing is found.
When working with static HTML sites in Nginx, we often want to achieve clean URLs that don't show the .html
extension. The directory structure in question looks like this:
public
|-- index.html
|-- media
| -- blurred_image-8.jpg
|-- post
| -- 13considerations
| -- index.html
The original Nginx configuration attempts to handle this with:
location / {
root /var/www/mysite/public;
try_files $uri $uri/ $uri/index.html;
}
This setup works for the root path (/
) but fails with 500 errors for nested paths like /post/13considerations/
. The issue lies in how try_files
handles directory structures.
Here's the correct configuration that handles both root and nested paths:
server {
listen 80;
server_name mysite.com;
root /var/www/mysite/public;
location / {
try_files $uri $uri/ $uri.html $uri/index.html =404;
}
location /media/ {
alias /var/www/mysite/public/media/;
error_page 404 = /404;
expires 30d;
}
location /static/ {
alias /var/www/mysite/public/static/;
error_page 404 = /404;
expires 30d;
}
}
The critical changes are:
- Moved
root
directive to server level for consistency - Modified
try_files
to check for.html
extension explicitly - Added proper fallback to 404 when no file is found
- Maintained separate handling for static assets
This configuration will now properly handle:
http://mysite.com/
→ servesindex.html
http://mysite.com/post/13considerations
→ serves/post/13considerations/index.html
http://mysite.com/about
→ serves/about.html
if exists
For better SEO and user experience, you might want to:
# Redirect .html requests to clean URLs
if ($request_uri ~ ^/(.*)\.html$) {
return 301 /$1;
}
# Ensure trailing slash for directories
if (-d $request_filename) {
rewrite [^/]$ $uri/ permanent;
}