# Nginx Alias vs Root Issues
Files exist on disk but Nginx returns 404. The path configuration looks correct, but something's wrong. The confusion between root and alias directives is one of the most common Nginx configuration errors. They behave differently, and mismatched trailing slashes compound the problem.
Understanding Root vs Alias
The key difference:
**root:** Appends the request URI to the path
**alias:** Replaces the location path with the alias path
**Example with root:**
``nginx
location /images/ {
root /var/www/data;
}
Request: /images/logo.png
Nginx looks for: /var/www/data/images/logo.png`
**Example with alias:**
``nginx
location /images/ {
alias /var/www/data/;
}
Request: /images/logo.png
Nginx looks for: /var/www/data/logo.png`
Check where Nginx is looking:
``bash
tail -f /var/log/nginx/error.log
# Shows: open() "/var/www/data/images/logo.png" failed (2: No such file or directory)
Common Cause 1: Using Root Instead of Alias
Files organized differently than URL structure.
Problematic config:
``nginx
location /downloads/ {
root /var/www/files;
}
Files are at /var/www/files/report.pdf but URL is /downloads/report.pdf.
Nginx looks for /var/www/files/downloads/report.pdf - doesn't exist.
Solution: Use alias:
``nginx
location /downloads/ {
alias /var/www/files/;
}
Request /downloads/report.pdf looks for /var/www/files/report.pdf - correct.
Common Cause 2: Using Alias Instead of Root
Alias used when root would be simpler.
Problematic config:
``nginx
location /static/ {
alias /var/www/html/static/;
}
Files at /var/www/html/static/css/style.css, URL /static/css/style.css.
This works with alias, but root is more appropriate:
Better: Use root:
``nginx
location /static/ {
root /var/www/html;
}
Request /static/css/style.css looks for /var/www/html/static/css/style.css - same result, simpler config.
Common Cause 3: Trailing Slash Mismatch
Trailing slashes must match for alias.
Problematic config:
``nginx
location /images {
alias /var/www/photos;
# No trailing slash on either
}
Request /images/logo.png:
- Location matched: /images (without trailing slash)
- Alias path: /var/www/photos
- Nginx constructs: /var/www/photoslogo.png (concatenated!)
Solution: Match trailing slashes:
``nginx
location /images/ {
alias /var/www/photos/;
# Both have trailing slash
}
Request /images/logo.png:
- Location matched: /images/
- URI after location: logo.png
- Nginx constructs: /var/www/photos/logo.png - correct
Or match both without trailing slash:
``nginx
location /images {
alias /var/www/photos;
# Neither has trailing slash
}
Request /images/logo.png:
- Location matched: /images
- URI part after location: /logo.png
- Nginx constructs: /var/www/photos/logo.png - correct
Common Cause 4: Alias with Regex Location
Alias doesn't work with regex locations capturing URI.
Problematic config:
``nginx
location ~ ^/download/(.*)$ {
alias /var/www/files/$1;
# This causes undefined behavior
}
Solution: Use root with regex:
``nginx
location ~ ^/download/(.*)$ {
root /var/www/files;
# Request /download/report.pdf
# Nginx looks for /var/www/files/download/report.pdf
}
Or rewrite to map the path:
``nginx
location ~ ^/download/(.*)$ {
set $file $1;
alias /var/www/files/$file;
}
Better: Use prefix location:
``nginx
location /download/ {
alias /var/www/files/;
}
Common Cause 5: Nested Location with Alias
Nested locations inherit parent's root/alias incorrectly.
Problematic config: ```nginx location /static { alias /var/www;
location /static/images { # Inherits parent's alias? No - needs own alias alias /var/www/images; # Wrong base } } ```
Solution: Define alias for nested location: ```nginx location /static/ { alias /var/www/;
location /static/images/ { alias /var/www/images/; } } ```
Or use root: ```nginx location /static { root /var/www;
location /static/images { # Inherits root /var/www # Request /static/images/logo.png # Looks for /var/www/static/images/logo.png } } ```
Common Cause 6: Index File Not Found with Alias
Alias location needs index file handling.
Problematic config:
``nginx
location /docs/ {
alias /var/www/documentation/;
# Request /docs/ returns 404
}
Request /docs/ needs index file, but alias doesn't automatically set document root for index.
Solution: Add index directive: ```nginx location /docs/ { alias /var/www/documentation/; index index.html index.htm;
try_files $uri $uri/ =404; } ```
Or set document root: ```nginx location /docs/ { alias /var/www/documentation/; index index.html;
if (-f $request_filename) { break; }
if (-d $request_filename) { rewrite ^(.*)$ $1/index.html last; } } ```
Common Cause 7: Alias Path Doesn't Exist
The alias directory doesn't exist on filesystem.
Diagnosis:
``bash
ls -la /var/www/photos/
Solution: Create directory:
``bash
sudo mkdir -p /var/www/photos
sudo chown www-data:www-data /var/www/photos
Common Cause 8: Alias for Location Without Trailing Slash
Using alias for location without trailing slash can cause issues.
Problematic config:
``nginx
location /api {
alias /var/www/api;
# Request /api returns 403 (directory index forbidden)
# Request /api/users is constructed incorrectly
}
Solution: Add trailing slashes:
``nginx
location /api/ {
alias /var/www/api/;
}
Or use internal rewrite:
``nginx
location = /api {
internal;
alias /var/www/api/index.html;
}
Verification Steps
- 1.Check where Nginx looks:
- 2.```bash
- 3.# Enable debug log
- 4.error_log /var/log/nginx/debug.log debug;
# Watch error log tail -f /var/log/nginx/error.log ```
- 1.Test file existence:
- 2.```bash
- 3.# Test with known URL
- 4.curl -I http://localhost/images/logo.png
# Check error log grep "open()" /var/log/nginx/error.log | tail -1 ```
- 1.Verify directory structure:
- 2.```bash
- 3.ls -la /var/www/data/images/
- 4.
` - 5.Check configuration:
- 6.```bash
- 7.sudo nginx -T | grep -A 10 "location /images"
- 8.
` - 9.Test both root and alias:
- 10.```nginx
- 11.# Add diagnostic header
- 12.add_header X-Path "$document_root$uri" always;
- 13.add_header X-Alias-Test $request_filename always;
- 14.
`
Complete Working Examples
Correct alias usage:
``nginx
# Files at /var/www/downloads/...
# URL /files/...
location /files/ {
alias /var/www/downloads/;
index index.html;
autoindex on;
}
Correct root usage: ```nginx # Files at /var/www/html/... # URL /... location / { root /var/www/html; index index.html; try_files $uri $uri/ =404; }
# Files at /var/www/html/static/... # URL /static/... location /static/ { root /var/www/html; expires 30d; } ```
Multiple aliased locations: ```nginx server { listen 80; server_name example.com;
# Main site location / { root /var/www/html; index index.html; }
# Downloads - different directory location /downloads/ { alias /var/www/files/; autoindex on; }
# Documentation - different directory location /docs/ { alias /var/www/documentation/; index index.html; }
# Images - same directory structure as URL location /images/ { root /var/www; # Uses /var/www/images/ } } ```
Quick Reference
| Directive | Path Construction | Use When |
|---|---|---|
root | path + URI | URL matches directory structure |
alias | alias + (URI - location) | URL differs from directory structure |
| Config | Request | File Looked For |
|---|---|---|
root /data; location /img/ | /img/logo.png | /data/img/logo.png |
alias /data/; location /img/ | /img/logo.png | /data/logo.png |
root /data; location /img | /img/logo.png | /data/img/logo.png |
alias /data; location /img | /img/logo.png | /data/logo.png |
alias /data; location /img/ | /img/logo.png | /datalogo.png (WRONG!) |
The critical rule: When using alias, location and alias must both have trailing slashes, or neither should have them. Root is simpler when URL structure matches filesystem structure.