Skip to main content

NGINX

The Pitfalls of add_header in NGINX: Solving Inheritance Issues with more_set_headers

by , , revisited on


We have by far the largest RPM repository with NGINX module packages and VMODs for Varnish. If you want to install NGINX, Varnish, and lots of useful performance/security software with smooth yum upgrades for production use, this is the repository for you.
Active subscription is required.

📅 Updated: January 28, 2026 (Originally published: September 15, 2023)

When it comes to NGINX configuration, the devil is often in the details. One common pitfall is the add_header directive’s inheritance behavior, which frequently leads to unexpected results. The more_set_headers directive from the headers-more module solves this problem elegantly.

The Inheritance Problem with add_header

In NGINX, configurations use a hierarchical structure with server, location, and nested blocks. The add_header directive has a non-intuitive behavior: if you define a header in a parent block and then use add_header again in a child block, the child completely overwrites all parent headers.

Consider this example:

server {
    add_header X-Server "NGINX";

    location / {
        add_header X-Location "Root";
    }
}

When you access a URL matching location /, only X-Location: Root appears in the response. The X-Server: NGINX header from the parent block is completely lost.

The Workaround (Repetitive and Error-Prone)

To make add_header work as expected, you must repeat every header in each child block:

server {
    add_header X-Server "NGINX";

    location / {
        add_header X-Server "NGINX";
        add_header X-Location "Root";
    }
}

This approach is tedious, error-prone, and difficult to maintain in complex configurations.

The Solution: more_set_headers

The more_set_headers directive from the headers-more module provides intuitive inheritance. Headers set in parent blocks are automatically included in child blocks:

server {
    more_set_headers "X-Server: NGINX";

    location / {
        more_set_headers "X-Location: Root";
    }
}

With this configuration, responses include both X-Server: NGINX and X-Location: Root headers – exactly what you’d expect.

Install the Headers-More Module

Step 1. Add GetPageSpeed Repository

For Rocky Linux, AlmaLinux, CentOS 8/9, or Fedora:

sudo dnf install -y https://extras.getpagespeed.com/release-latest.rpm

For CentOS/RHEL 7:

sudo yum install -y https://extras.getpagespeed.com/release-latest.rpm

Note: An active NGINX Extras subscription is required for RHEL-based systems. Fedora users have free access.

Step 2. Install the Module

For Rocky Linux, AlmaLinux, CentOS 8/9, or Fedora:

sudo dnf -y install nginx-module-headers-more

For CentOS/RHEL 7:

sudo yum -y install nginx-module-headers-more

Step 3. Enable the Module

Add the following at the top of /etc/nginx/nginx.conf:

load_module modules/ngx_http_headers_more_filter_module.so;

Step 4. Reload NGINX

sudo systemctl reload nginx

When to Use Each Directive

Use Case Recommended Directive
Simple, single-location headers add_header is fine
Headers that should inherit to child blocks more_set_headers
Complex multi-level configurations more_set_headers
Removing or clearing headers more_clear_headers
Modifying upstream response headers more_set_headers with -s flag

Additional Capabilities

The headers-more module provides more than just more_set_headers:

  • more_clear_headers – Remove headers from responses
  • more_set_input_headers – Modify request headers before processing
  • more_clear_input_headers – Remove request headers

Summary

The primary difference between add_header and more_set_headers is inheritance behavior. Use more_set_headers for intuitive, maintainable header management in complex NGINX configurations.

D

Danila Vershinin

Founder & Lead Engineer

NGINX configuration and optimizationLinux system administrationWeb performance engineering

10+ years NGINX experience • Maintainer of GetPageSpeed RPM repository • Contributor to open-source NGINX modules

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This site uses Akismet to reduce spam. Learn how your comment data is processed.