How to enable the Nginx stub_status page

Enabling a protected stub_status endpoint in Nginx exposes live connection and request counters that help confirm whether the web tier is backed up under traffic, stalled behind slow clients, or simply idling normally. The page is small, immediate, and useful during incidents, load tests, or initial monitoring setup.

The stub_status directive from ngx_http_stub_status_module publishes a plain-text snapshot that includes Active connections plus cumulative accepts, handled, and requests counters, followed by the current Reading, Writing, and Waiting states. It is usually placed in a dedicated exact-match location inside a server block and queried with curl or a monitoring collector.

Examples below use packaged Nginx on Debian or Ubuntu, where site files commonly live under /etc/nginx/sites-available and reloads use nginx.service. Source builds need the module compiled with --with-http_stub_status_module, and any allowlist must match the client address that Nginx actually sees, so reverse-proxy or load-balancer deployments may need real-IP handling before off-box access rules behave as intended.

Steps to enable the Nginx stub_status page:

  1. Confirm that the installed Nginx build includes the stub_status module.
    $ nginx -V 2>&1 | grep -- --with-http_stub_status_module
    configure arguments: ##### snipped ##### --with-http_stub_status_module ##### snipped #####

    Packaged builds on Debian and Ubuntu normally include the module, while source builds need the --with-http_stub_status_module configure option.

  2. Open the server block file that should expose the status endpoint.
    $ sudo vi /etc/nginx/sites-available/example.com.conf

    On layouts without sites-available, edit the loaded server block file under /etc/nginx/conf.d/ or another path included from /etc/nginx/nginx.conf.

  3. Add an exact-match status location inside that server block.
    location = /nginx_status {
        stub_status;
        access_log off;
        allow 127.0.0.1;
        allow ::1;
        deny all;
    }

    Rules are checked in order until the first match, so keep every allow line before deny all and use location = /nginx_status to avoid matching subpaths such as /nginx_status/foo.

  4. Test the Nginx configuration for syntax errors.
    $ sudo nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
  5. Reload Nginx to apply the updated configuration.
    $ sudo systemctl reload nginx

    Use sudo nginx -s reload when systemd is not managing the service.

  6. Query the local status endpoint and confirm that the counters are returned.
    $ curl -s http://127.0.0.1/nginx_status
    Active connections: 1 
    server accepts handled requests
     3 3 3 
    Reading: 0 Writing: 1 Waiting: 0 

    The accepts, handled, and requests values are cumulative counters, while Active connections, Reading, Writing, and Waiting show the current connection state.

  7. Query the same path from an address or network that is not on the allowlist.
    $ curl -i --interface 127.0.0.2 http://127.0.0.1/nginx_status
    HTTP/1.1 403 Forbidden
    Server: nginx/1.24.0 (Ubuntu)
    Date: Thu, 09 Apr 2026 12:50:22 GMT
    Content-Type: text/html
    Content-Length: 162
    Connection: keep-alive
    
    <html>
    <head><title>403 Forbidden</title></head>
    <body>
    <center><h1>403 Forbidden</h1></center>
    <hr><center>nginx/1.24.0 (Ubuntu)</center>
    </body>
    </html>

    A 200 response from an untrusted address means the endpoint is exposed and the allow or deny rules need correction immediately.