← Back to Apache Course | Chapter 3: Modules | Lesson 4 of 5

mod_headers

mod_headers lets you add, change, or remove HTTP response and request headers from the Apache config -- used constantly for security headers, caching hints, and CORS.

Enabling It

On Ubuntu/Debian: sudo a2enmod headers then reload. On RHEL-family systems it's typically compiled in and just needs LoadModule headers_module modules/mod_headers.so uncommented.

The Header Directive

Header set Name "value" sets a response header, overwriting any existing one with that name. Header add appends a new header without removing an existing one of the same name. Header unset and Header always unset remove a header entirely -- useful for stripping information like Server or X-Powered-By that reveals server internals.

Conditional Headers

Header can take a condition, most commonly Header always set ..., where always makes sure the header is set even on error responses (4xx/5xx), not just successful ones -- important for security headers, which should apply to every response, not only the happy path.

Security and Caching Use Cases

The most common real-world use of mod_headers is adding security headers (covered in depth in the Security Headers lesson) like X-Content-Type-Options and Strict-Transport-Security, plus caching headers like Cache-Control on static asset directories to tell browsers how long to keep a file before re-requesting it.

Example: Setting security and caching headers

apacheconf
<IfModule mod_headers.c>
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header unset Server
</IfModule>

<FilesMatch "\.(css|js|jpg|png)$">
    Header set Cache-Control "max-age=604800, public"
</FilesMatch>
{# Flagged by hand after confirming a runner can't handle this example (a shell command / go.mod file stored as a TopicExample, a language feature the configured runner version doesn't support, or output that blows a runner's sandbox limit) -- see TopicExample.norun. Never render the run button for these, regardless of language, since it would just fail at execute_code (or worse, hang the Judge0 queue on a submission that can never finish cleanly). #}

⚠️ This example can't run in the browser editor. Try it in your own local environment instead.

{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Using Header set without always for a security header, so it's missing exactly on the error responses (like a blocked request) where it matters most.
  2. Forgetting mod_headers needs to be enabled separately -- writing Header directives that Apache doesn't recognize at all until the module is on.
  3. Setting conflicting Cache-Control headers in both the application and in Apache's config, leaving it unclear which one actually wins for a given response.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.