When trying to configure Nginx as a TCP/UDP load balancer using the stream
directive, many administrators encounter the frustrating "unknown directive" error despite having Nginx 1.12.0+ installed. The root cause lies in how the stream module gets compiled.
From your nginx -V
output, we can see a critical detail:
--with-stream=dynamic
This means the stream module was compiled as a dynamic module rather than being built directly into the binary. While Nginx 1.12.0 includes stream capabilities, they need explicit loading.
Add this line at the very top of your nginx.conf
:
load_module modules/ngx_stream_module.so;
Then verify the module loads:
sudo nginx -t
sudo systemctl restart nginx
Here's a verified UDP load balancing configuration that works after module loading:
load_module modules/ngx_stream_module.so;
events {
worker_connections 1024;
}
stream {
upstream dns_servers {
server 172.16.1.10:9516 weight=2;
server 172.16.1.11:9516;
}
server {
listen 9516 udp reuseport;
proxy_pass dns_servers;
proxy_timeout 1s;
proxy_responses 1;
error_log /var/log/nginx/stream_error.log;
}
}
If dynamic loading fails, consider:
- Compiling from source with
--with-stream
(non-dynamic) - Using the official Nginx repository instead of PPAs:
sudo apt-get remove --purge nginx*
sudo apt-get install curl gnupg2 ca-certificates lsb-release
echo "deb http://nginx.org/packages/mainline/ubuntu lsb_release -cs nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo apt-key add -
sudo apt-get update
sudo apt-get install nginx-plus-module-stream
- Verify module files exist:
ls /usr/lib/nginx/modules/
- Check for conflicting PPA versions
- Ensure no syntax errors in other config sections
- Monitor error logs:
tail -f /var/log/nginx/error.log
When examining the nginx -V
output, I noticed a crucial detail in the configure arguments:
--with-stream=dynamic
This indicates the stream module was compiled as dynamic rather than built-in. This explains why the directive isn't recognized even though you're using Nginx 1.12.0 which technically includes the stream module.
First, let's verify where your modules are stored:
ls -la /usr/lib/nginx/modules/
You should see ngx_stream_module.so
among the files. If not, you'll need to install it separately.
Edit your nginx.conf
and add this line at the very top (before any events or http blocks):
load_module modules/ngx_stream_module.so;
Here's a working configuration for UDP stream proxying:
load_module modules/ngx_stream_module.so;
events {
worker_connections 1024;
}
stream {
upstream dns_servers {
server 172.16.1.1:9516;
server 172.16.1.2:9516;
}
server {
listen 9516 udp reuseport;
proxy_pass dns_servers;
proxy_timeout 1s;
proxy_responses 1;
}
}
After making changes, always test your configuration:
sudo nginx -t
If successful, reload nginx:
sudo systemctl reload nginx
If the dynamic module isn't available, you might need to compile Nginx with stream support:
./configure --with-stream --with-stream_ssl_module
make
sudo make install
- Make sure the
load_module
directive appears before any stream blocks - Check file permissions on the module file
- Verify your Nginx worker has permission to bind to the port
- For UDP, always include
reuseport
for better performance