Deep Analysis and Practical Guide to $request_uri vs $uri Variables in NGINX

Nov 26, 2025 · Programming · 10 views · 7.8

Keywords: NGINX | URI_Variables | Request_Processing | Configuration_Optimization | Web_Server

Abstract: This technical paper provides an in-depth examination of the fundamental differences, processing mechanisms, and practical applications between NGINX's $request_uri and $uri variables. Through detailed analysis of URI normalization processes, variable characteristic comparisons, and real-world configuration examples, developers will learn when to use $uri for standardized processing and when $request_uri is necessary for preserving original request information. The article combines official documentation with practical cases to deliver best practices for map directives, rewrite rules, and logging scenarios while avoiding common pitfalls like double encoding and matching errors.

Core Concept Analysis

In NGINX configuration, $request_uri and $uri are two frequently confused but fundamentally different variables. Understanding their distinctions is crucial for writing correct and efficient configurations.

The $request_uri variable always contains the original request URI sent by the client, including query string parameters. For example, for a request to /foo/bar.php?arg=baz, $request_uri holds the complete /foo/bar.php?arg=baz. This variable remains unchanged throughout request processing and is not modified by any internal NGINX operations.

In contrast, the $uri variable represents the URI currently being processed by NGINX, which undergoes multiple levels of normalization:

Normalization Processing Mechanism

NGINX's URI normalization is a multi-stage process. When a request arrives, NGINX first parses the original $request_uri, then applies a series of normalization rules to generate the processing-ready $uri.

Consider the request /api//v1/users%2Finfo?page=1:

This normalization ensures URI consistency, preventing matching issues caused by format variations. In scenarios such as location block matching, rewrite rule processing, and file path resolution, using the normalized $uri provides more reliable results.

Variable Characteristics Comparison

<table><tr><th>Characteristic</th><th>$request_uri</th><th>$uri</th></tr><tr><td>Content Completeness</td><td>Contains complete original URI with query parameters</td><td>Contains only path portion, query parameters removed</td></tr><tr><td>Encoding Handling</td><td>Preserves original URL encoding</td><td>URL-encoded characters are decoded</td></tr><tr><td>Path Normalization</td><td>No path compression applied</td><td>Consecutive slashes compressed, relative paths resolved</td></tr><tr><td>Mutability</td><td>Remains constant throughout request lifecycle</td><td>May change due to internal redirects</td></tr>

Practical Application Scenarios

Selection in Map Directives

Choosing between $uri and $request_uri as input parameters for map directives depends on specific matching requirements:

# Mapping based on normalized URI - recommended for path matching
map $uri $new_uri {
    /api/v1/users    /api/v2/users;
    /old-path        /new-path;
    default          $uri;
}

This configuration is suitable for pattern matching on normalized paths, avoiding matching failures caused by URL encoding or extra slashes.

# Mapping based on original request URI - suitable for query parameter scenarios
map $request_uri $redirect_url {
    ~* "^/search\?q=([^&]+)"   https://external-site.com/search?query=$1;
    default                     "";
}

When matching logic requires access to query string parameters, $request_uri must be used since $uri has already removed the query portion.

Avoiding Double Encoding Issues

A common mistake is improper variable usage in scenarios involving URL-encoded characters:

# Incorrect example: may cause double encoding
location /api/ {
    if ($request_uri ~* "users%2F") {
        return 301 /new-location;
    }
}

The correct approach uses the normalized $uri:

# Correct example: using normalized URI
location /api/ {
    if ($uri = "/api/v1/users/info") {
        return 301 /api/v2/users/info;
    }
}

Logging and Debugging

Recording both variables in access logs provides comprehensive request tracing:

log_format detailed '$remote_addr - $remote_user [$time_local] '
                   '"$request" $status $body_bytes_sent '
                   '"$http_referer" "$http_user_agent" '
                   'original_uri: "$request_uri" '
                   'normalized_uri: "$uri"';

access_log /var/log/nginx/access.log detailed;

This configuration aids in debugging URI processing issues by clearly showing differences between original requests and processed URIs.

Best Practice Recommendations

Scenarios favoring $uri usage:

Scenarios requiring $request_uri usage:

Configuration validation techniques:

When uncertain which variable to use, temporary configuration can reveal differences:

location /debug/ {
    add_header X-Debug-Request-Uri $request_uri;
    add_header X-Debug-Uri $uri;
    return 200 "OK";
}

By sending requests to /debug/test%2Fpath?param=value, specific values of both variables appear in response headers, facilitating correct selection.

Common Issues and Solutions

Issue 1: Why doesn't my rewrite rule match?

This typically occurs when $request_uri is incorrectly used where $uri should be, or vice versa. Check if the URI contains query parameters or URL-encoded characters to select the appropriate variable.

Issue 2: How to avoid URL double encoding?

Use $uri in most processing scenarios since URL encoding has been properly decoded. Only use $request_uri when original encoding information is genuinely needed.

Issue 3: When are both variables equal?

$uri and $request_uri have identical values when the original request URI contains no query string, URL-encoded characters, consecutive slashes, or relative path components. However, this scenario is relatively uncommon in production environments.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.