Nginx’s powerful URL rewriting and location matching capabilities can sometimes become a source of confusion and unexpected behavior. Here’s how to debug and solve common issues with rewrite rules and location blocks.
Understanding Location Block Priority
Nginx processes location blocks in a specific order:
- Exact match (
=
) – highest priority - Preferential prefix match (
^~
) - Regular expression match (
~
and~*
) – in order of appearance - Prefix match – lowest priority
Common Issues and Solutions
1. Rewrite Rules Not Working
If your rewrite rules aren’t working as expected:
nginxserver {
# Enable rewrite logging
error_log /var/log/nginx/rewrite.log notice;
rewrite_log on;
# Test your rewrite rule
location /old-path {
rewrite ^/old-path/(.*)$ /new-path/$1 last;
}
}
Check the logs to see how the rewrite is being processed:
bashtail -f /var/log/nginx/rewrite.log
2. Location Block Precedence Issues
When multiple location blocks might match:
nginxserver {
# This exact match has highest priority
location = /exact {
return 200 "Exact match\n";
}
# This will match before the regex below
location ^~ /prefix {
return 200 "Preferential prefix match\n";
}
# Regex matches are checked in order
location ~ ^/regex-[0-9] {
return 200 "Regex match\n";
}
# Standard prefix match has lowest priority
location /prefix {
return 200 "Standard prefix match\n";
}
}
Test with curl to verify the expected behavior:
bashcurl -i http://example.com/exact
curl -i http://example.com/prefix
curl -i http://example.com/regex-1
3. Location Block Inheritance
Understanding how directives are inherited:
nginxserver {
# Server-level setting
set $test "server";
location /parent {
# This location inherits server-level settings
# and can override them
set $test "parent";
# Debug output
add_header X-Debug-Var $test;
location /parent/child {
# This inherits from parent location
# unless explicitly overridden
# Debug output
add_header X-Debug-Var $test;
}
}
}
4. Capturing and Using Variables
Debug variable capture and usage:
nginxserver {
location ~* ^/product/(?<product_id>[0-9]+)$ {
# Capture product_id and log it
add_header X-Debug-Product-ID $product_id;
# Log to error log for debugging
error_log /var/log/nginx/variable_debug.log notice;
# You can then use $product_id in proxy_pass
# proxy_pass http://backend/api/product/$product_id;
return 200 "Product ID: $product_id\n";
}
}
5. Resolving Try_Files Issues
Common try_files debugging:
nginxserver {
root /var/www/html;
location / {
# Debug which file is being tested
error_log /var/log/nginx/try_files_debug.log notice;
# Try files in this order:
try_files $uri $uri/ /index.php?$args;
}
}
Add logging before try_files to debug:
nginxlocation / {
# Log the URI being tested
if ($request_uri) {
set $path_info "Testing: $document_root$uri, URI: $request_uri";
error_log /var/log/nginx/try_files_debug.log notice;
}
try_files $uri $uri/ /index.php?$args;
}
6. Complex Rewrite Debugging Example
For a more complex setup like a REST API:
nginxserver {
# Enable detailed logging
error_log /var/log/nginx/rewrite.log notice;
rewrite_log on;
location /api/ {
# Log rewrite parameters
if ($request_uri) {
set $debug_info "URI: $request_uri, Args: $args";
error_log /var/log/nginx/api_debug.log notice;
}
# API versioning rewrite
rewrite ^/api/v1/users/([0-9]+)$ /api/users.php?id=$1&version=1 last;
rewrite ^/api/v2/users/([0-9]+)$ /api/users.php?id=$1&version=2 last;
# After rewrite processing
if ($request_uri) {
set $debug_info "After rewrite - URI: $request_uri, Args: $args";
error_log /var/log/nginx/api_debug.log notice;
}
}
}
Testing Tools and Techniques
- Curl with verbose output: bash
curl -v http://example.com/path/to/test
- Temporary debug response: nginx
location /debug { # Return debug info instead of normal processing return 200 "URI: $request_uri\nArgs: $args\nDocument Root: $document_root\n"; }
- Map variables for debugging: nginx
map $request_uri $debug_uri { ~^/api/v1/(.*)$ "API v1: $1"; ~^/api/v2/(.*)$ "API v2: $1"; default "No match"; } server { location / { add_header X-Debug-Info $debug_uri; } }
By using these debugging techniques, you can systematically identify and resolve issues with Nginx rewrite rules and location blocks, leading to properly functioning URL routing for your web applications.