yum upgrades for production use, this is the repository for you.
Active subscription is required.
Standard NGINX configuration handles strings well, but it lacks native support for lists of values. If you need to split a comma-separated query parameter into individual items, transform each one, and reassemble them, you know the limitations. The NGINX array variables module solves this by introducing array-typed variables directly into your config.
In this article, you will learn how to install, configure, and use the NGINX array variables module. You will see practical examples for building dynamic SQL conditions, transforming user input, and processing delimited data — all without external scripts.
What Are NGINX Array Variables?
The array-var-nginx-module, created by Yichun Zhang (author of OpenResty), adds array-typed variables to NGINX. Under the hood, it stores binary pointers to NGINX’s internal ngx_array_t C data structure within regular string variables.
This means you can perform operations common in programming languages but traditionally impossible in NGINX config files:
- Split a delimited string into individual elements
- Map a transformation to every element in an array
- Join array elements back into a single string
- Apply NGINX directives to each element using higher-order operations
The module provides four directives: array_split, array_join, array_map, and array_map_op. It also exposes the $array_it iterator variable for use within array_map templates. Together, these tools bring functional programming concepts to your NGINX configuration.
Why Use This Module?
You might wonder why you would process arrays at the NGINX level. There are several compelling reasons:
- Reduced backend load: Transform and validate data before it reaches your application
- Dynamic query construction: Build SQL
WHEREclauses from URL parameters - Input sanitization at the edge: Escape user-supplied values before they reach your backend
- URL parameter manipulation: Split, transform, and reconstruct query strings for routing
- Logging flexibility: Decompose complex parameters for structured logging
However, for complex logic beyond split/map/join operations, consider the Lua NGINX module instead. It provides full scripting capabilities within NGINX.
Installation
The NGINX array variables module depends on the NGINX Development Kit (NDK). This framework provides the underlying infrastructure for variable manipulation. Both modules must be installed and loaded.
RHEL, CentOS, AlmaLinux, Rocky Linux, and Amazon Linux
First, enable the GetPageSpeed repository. Then install the module package:
sudo dnf install https://extras.getpagespeed.com/release-latest.rpm
sudo dnf install nginx-module-array-var
The NDK dependency is installed automatically. After installation, add these lines at the very top of /etc/nginx/nginx.conf, before the events block:
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_array_var_module.so;
Important: The NDK module must load before the array-var module. If you reverse the order, NGINX fails to start with an undefined symbol: ndk_set_var_value error.
Debian and Ubuntu
First, set up the GetPageSpeed APT repository, then install:
sudo apt-get update
sudo apt-get install nginx-module-array-var
On Debian/Ubuntu, the package handles module loading automatically. No
load_moduledirective is needed.
You can find more details on the RPM module page or the APT module page.
Verify the Installation
After adding the load_module directives (on RHEL-based systems), test your config:
sudo nginx -t
If the test passes, reload NGINX:
sudo systemctl reload nginx
Directive Reference
The NGINX array variables module provides four directives. All are valid in the http, server, and location contexts (including if blocks).
array_split
Syntax: array_split <separator> <subject> [max_items] [to=$target_variable]
Default: none
Context: http, server, location
Splits the string in subject by the separator and stores the result as an array variable.
Basic usage — split in-place (the source variable becomes an array):
array_split "," $arg_names;
With target variable — store the result in a different variable:
array_split "," $arg_names to=$names_array;
With max items — limit the number of resulting elements:
array_split "," $arg_data 3 to=$items;
When you set a maximum, the last element contains the unsplit remainder. Splitting "a,b,c,d,e" with max 3 produces: a, b, and c,d,e.
Empty separator — splits the string into individual characters:
array_split "" $arg_word to=$chars;
array_join
Syntax: array_join <separator> $array_var [to=$target_variable]
Default: none
Context: http, server, location
Joins all elements of an array variable into a single string. It uses the specified separator between elements. This directive converts an array back into a regular string for use with echo, return, or proxy_set_header.
In-place join — the array variable becomes a string:
array_join " + " $names;
With target variable — preserve the original array:
array_join " | " $names to=$result;
array_map
Syntax: array_map <template> $array_var [to=$new_array_var]
Default: none
Context: http, server, location
Applies a string template to each element of an array. Inside the template, use $array_it to reference the current element.
In-place mapping — modifies the array directly:
array_map "[$array_it]" $names;
This wraps each element in square brackets. If $names contained Alice, Bob, Charlie, it becomes [Alice], [Bob], [Charlie].
With target variable — keep the original array unchanged:
array_map "item=$array_it" $names to=$formatted;
You can use any NGINX variables inside the template alongside $array_it:
set $prefix "user";
array_map "${prefix}_$array_it" $names;
array_map_op
Syntax: array_map_op <directive> $array_var [to=$new_array_var]
Default: none
Context: http, server, location
This is a higher-order directive. It applies another NGINX directive to each element of an array. The directive must use the NDK’s set_var interface. In practice, this means directives from the set-misc module:
set_quote_sql_str— escapes for safe SQL string literalsset_quote_pgsql_str— escapes for PostgreSQLset_quote_json_str— escapes for JSON stringsset_escape_uri— URL-encodes valuesset_unescape_uri— URL-decodes valuesset_encode_base64/set_decode_base64— Base64 encodingset_sha1/set_md5— hash computation
In-place operation:
array_map_op set_quote_sql_str $names;
With target variable:
array_map_op set_escape_uri $names to=$escaped_names;
To use array_map_op, install the module that provides your target directive. For example, install nginx-module-set-misc:
sudo dnf install nginx-module-set-misc
Then load it in your nginx.conf (after NDK):
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_set_misc_module.so;
load_module modules/ngx_http_array_var_module.so;
The $array_it Variable
The $array_it variable is a special iterator. It is only meaningful inside an array_map template. It references the current array element during iteration. Outside of array_map, this variable is empty.
Practical Use Cases
Now that you understand each directive, let us walk through scenarios where NGINX array variables prove most useful.
Building Dynamic SQL Conditions
One of the most powerful applications is constructing safe SQL WHERE clauses. You can build these from user-supplied comma-separated parameters. This works well when NGINX talks directly to a database backend.
location /api/search {
# Split the comma-separated "tags" parameter
array_split ',' $arg_tags to=$tags;
# Escape each tag for safe SQL inclusion
array_map_op set_quote_sql_str $tags;
# Wrap each escaped tag in a condition
array_map "tag = $array_it" $tags;
# Join with OR to form the WHERE clause
array_join ' OR ' $tags to=$where_clause;
# Pass to backend via header
proxy_set_header X-SQL-Filter $where_clause;
proxy_pass http://backend;
}
A request to /api/search?tags=nginx,performance,security generates:
tag = 'nginx' OR tag = 'performance' OR tag = 'security'
Each value is properly quoted by set_quote_sql_str. This prevents SQL injection attacks. A malicious input like nginx'; DROP TABLE-- is safely escaped to 'nginx\'; DROP TABLE--'.
Processing CSV Data from Query Parameters
Suppose your application receives file paths as a comma-separated parameter. You can split, transform, and reassemble this data:
location /files {
array_split ',' $arg_files to=$file_list;
array_map "/data/$array_it" $file_list;
array_join '|' $file_list to=$internal_paths;
proxy_set_header X-File-Paths $internal_paths;
proxy_pass http://file-server;
}
A request to /files?files=report.pdf,data.csv,image.png produces:
/data/report.pdf|/data/data.csv|/data/image.png
URL Encoding Array Elements
When passing array values as URL parameters to an upstream, use set_escape_uri for proper encoding:
location /redirect {
array_split ',' $arg_params to=$params;
array_map_op set_escape_uri $params;
array_map "p=$array_it" $params;
array_join '&' $params to=$qs;
return 302 /destination?$qs;
}
Note: Avoid using $query_string as a target variable name. It is a built-in NGINX variable and cannot be overwritten.
Limiting Split Results
Sometimes you only need the first few items from a delimited string. The max_items parameter handles this:
location /preview {
# Take first 3 tags only
array_split ',' $arg_tags 3 to=$preview_tags;
array_join ', ' $preview_tags to=$display;
add_header X-Preview-Tags $display;
proxy_pass http://backend;
}
With ?tags=a,b,c,d,e,f, only three elements are produced: a, b, and c,d,e,f. The last element holds all remaining items. This prevents large arrays from consuming memory.
Performance Considerations
The NGINX array variables module operates entirely in memory. It runs within NGINX’s request processing cycle. Therefore, the performance impact is minimal for typical use cases. Keep these points in mind:
- Array size: Each element allocates memory from the request pool. Very large arrays (thousands of elements) increase memory per request.
- map_op overhead:
array_map_opcalls another directive’s handler for each element. Expensive directives likeset_sha1multiply in cost. - Avoid unnecessary splits: Only split when you need individual elements. If you just pass a comma-separated string through, do not split it.
For high-traffic servers, set a reasonable max_items limit to cap resource usage.
Troubleshooting
“undefined symbol: ndk_set_var_value”
This error means the NDK module is not loaded before array-var. Fix the order:
load_module modules/ndk_http_module.so; # Must be first
load_module modules/ngx_http_array_var_module.so; # After NDK
“directive not found or does not use ndk_set_var_value”
This array_map_op error means the directive you specified either does not exist or is not NDK-compatible. Verify that:
- The module providing the directive is installed and loaded
- The directive supports the NDK
set_varinterface
Most set-misc module directives are compatible. Standard NGINX directives like set or return are not.
“invalid array variable value”
This error from array_join, array_map, or array_map_op means you passed a regular string instead of an array. Only variables created by array_split or array_map (with to=) hold valid array types. Ensure you call array_split before join or map.
Empty or Missing Output
If array_join produces an empty result, check that:
- The source query parameter contains data (test with
echo $arg_paramname) - The
array_splitseparator matches the delimiter in the data - You are not overwriting the variable between operations
You can use the NGINX echo module for debugging variable values during development.
Security Best Practices
When processing user input with NGINX array variables, follow these guidelines:
- Always escape before SQL usage: Use
array_map_op set_quote_sql_strfor any SQL fragment built from user data - Limit array sizes: Use
max_itemsto prevent denial-of-service attacks with thousands of values - Validate input early: Use NGINX’s
mapdirective to reject invalid input before splitting - Do not expose internals: Avoid returning raw array-joined content to clients
For additional NGINX security hardening, see our guide on security headers.
Comparison with Alternative Approaches
The NGINX array variables module is not the only way to process lists. Here is how it compares:
| Approach | Pros | Cons |
|---|---|---|
| array-var module | Lightweight, no scripting, fast | Limited to split/map/join |
| Lua NGINX module | Full language, conditionals, loops | Heavier dependency |
| NGINX map directive | Built-in, no extra modules | Cannot iterate dynamic lists |
| Backend processing | Most flexible | Adds latency, more backend load |
For simple list processing, NGINX array variables strike the best balance. For complex logic with conditionals or loops, choose the Lua module.
Conclusion
The NGINX array variables module fills an important gap in NGINX’s config language. With four directives — array_split, array_join, array_map, and array_map_op — you can split delimited strings, transform each element, and reassemble them.
This module is especially useful for system administrators who need to process query parameters, build dynamic SQL conditions, or manipulate URL components. Combined with the set-misc module, it provides a powerful yet lightweight data transformation toolkit.
The source code is available on GitHub. Pre-built packages are available from the GetPageSpeed repository for all major Linux distributions.
