Forward query parameters through Nginx proxy_pass
Understand when proxy_pass preserves query strings, how rewrite appends arguments, and how to test encoded or repeated parameters.
proxy_pass normally forwards query parameters without extra configuration. The main distinction is between changing the request path and changing its arguments. A trailing slash in the upstream URL can replace a path prefix while preserving the query string.
Forward the original request
location / {
proxy_pass http://127.0.0.1:8080;
}
With no prior rewrite, /search?q=nginx&page=2 reaches the backend with the same path and arguments.
Replace a prefix while keeping arguments
location /api/ {
proxy_pass http://127.0.0.1:8080/;
}
/api/users?x=1 becomes /users?x=1. Without the URI component / on proxy_pass, it remains /api/users?x=1. Neither basic form requires appending $args manually.
Variable-based proxy_pass and prior rewrites have additional URI rules. In particular, specifying a URI in a variable-based upstream URL can replace the whole forwarded URI rather than applying ordinary prefix replacement.
Understand rewrite argument handling
These are separate alternatives:
# Keep existing arguments.
rewrite ^/old/(.*)$ /new/$1 break;
# Discard existing arguments.
rewrite ^/old/(.*)$ /new/$1? break;
# Add type=fixed before the original arguments.
rewrite ^/old/(.*)$ /new/$1?type=fixed break;
# Use only type=fixed.
rewrite ^/old/(.*)$ /new/$1?type=fixed? break;
When the replacement supplies arguments, Nginx appends the original arguments unless the replacement ends with ?. Adding $args yourself without suppressing that automatic append can duplicate them.
Read or change arguments explicitly
$args contains the current query string, $is_args is ? when arguments exist, and $arg_uid reads the uid argument. For example:
location / {
proxy_set_header X-User-Id $arg_uid;
proxy_pass http://127.0.0.1:8080;
}
A client-supplied uid is not authenticated identity; do not use that header as authorization evidence.
For a specific route, append a fixed argument with the same rewrite rule:
location /search {
rewrite ^/search$ /search?source=proxy break;
proxy_pass http://127.0.0.1:8080;
}
This appends the original arguments after source=proxy. Decide how the backend should handle a client that also supplies source.
Verify edge cases
Send requests with repeated keys, empty values, and percent-encoded characters. Compare the proxy entry with what the backend received, redacting secrets. An HTTP 400 alone does not prove that Nginx dropped arguments.
FAQ
Does Nginx normalize the URL?
A no-URI proxy_pass can forward the original client request URI unchanged. A URI replacement or rewrite operates on a normalized path. Do not assume every mode preserves path encoding byte for byte; test signed URLs and encoded path separators explicitly.
Why does text look corrupted at the backend?
Check client encoding and the application's query decoding, including whether it decodes more than once. Avoid reconstructing an already encoded query unnecessarily.
Can a parameter select an upstream?
Use map in the http context to map an allowlisted parameter value to known upstream groups, then reference that variable. Do not turn arbitrary user input into a destination URL.
References: proxy_pass URI rules, rewrite argument rules.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan