loop-detect: CDN-Loop header support for request loop prevention
Installation
You can install this module in any RHEL-based distribution, including, but not limited to:
- RedHat Enterprise Linux 7, 8, 9 and 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 and Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-loop-detect
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-loop-detect
Enable the module by adding the following at the top of /etc/nginx/nginx.conf:
load_module modules/ngx_http_loop_detect_module.so;
This document describes nginx-module-loop-detect v0.1.0 released on Jan 06 2026.
http {
# Enable the module in a location block
loop_detect on;
loop_detect_cdn_id my_cdn_id;
loop_detect_status 508;
loop_detect_max_allow_loops 10;
server {
listen 80;
server_name example.com;
location / {
proxy_set_header CDN-Loop $loop_detect_proxy_add_cdn_loop;
proxy_pass http://example.upstream.com;
}
}
}
Directives
loop_detect
Syntax: loop_detect on | off;
Default: loop_detect off;
Context: http, server, location
Enables or disables the loop detection for the current scope. When enabled, the module checks the CDN-Loop header to track the number of hops and blocks requests exceeding the allowed limit.
loop_detect_cdn_id
Syntax: loop_detect_cdn_id string;
Default: loop_detect_cdn_id openresty;
Context: http, server, location
Sets the unique identifier for your clusters. This identifier is used to parse and track loops in the CDN-Loop header.
loop_detect_status
Syntax: loop_detect_status code;
Default: loop_detect_status 508;
Context: http, server, location
Sets the HTTP status code returned when a request exceeds the allowed loop limit. The code must be between 400 and 599 (client or server errors).
loop_detect_max_allow_loops
Syntax: loop_detect_max_allow_loops number;
Default: loop_detect_max_allow_loops 10;
Context: http, server, location
Sets the maximum number of allowed loops before blocking the request. The number must be greater than 0.
Variables
$loop_detect_current_loops
Returns the current detected loop count extracted from the CDN-Loop header. This value represents the number of hops your request has already passed through CDN nodes.
$loop_detect_proxy_add_cdn_loop
Constructs the new CDN-Loop header value to be sent to downstream proxies. This value includes:
- The current CDN node's identifier and incremented loop count (e.g.,
my_cdn; loops=2). - Remaining other entries from the original
CDN-Loopheader (if any).
Example Usage:
location / {
proxy_set_header CDN-Loop $loop_detect_proxy_add_cdn_loop;
proxy_pass http://backend;
}
How It Works
-
Detection: The module parses the
CDN-Loopheader to identify the number of hops. Each hop is formatted as: Format:Cdn-Loop: <cdn_id>; loops=<count>, ...Example:Cdn-Loop: my_cdn; loops=2, another_cdn; loops=1. -
Tracking: The current hop count (current_loops) is extracted from the header. The module increments the count and constructs a new
CDN-Loopvalue for downstream proxies. -
Blocking: If the detected loop count exceeds
loop_detect_max_allow_loops, NGINX returns the configuredloop_detect_status(e.g., 508).
GitHub
You may find additional configuration tips and documentation for this module in the GitHub repository for nginx-module-loop-detect.