Apache · Configuration and operations

How do you write correct and safe mod_rewrite rules?

Hardmod_rewriteregexredirectsUpdated Oct 2026
Quiz this track

Short answer

Anchor patterns, account for per-directory context, use specific flags and test with trace logging. Avoid broad catch-all rules, preserve query strings deliberately and prefer END when a rule must stop all rewriting.

Most rewrite bugs come from context and ordering. In directory context the leading slash is already removed, so a pattern written for vhost context will not match. Rules are processed repeatedly after internal rewrites, so an unanchored pattern can keep matching its own output and loop until Apache returns 500.

apache
RewriteEngine On
RewriteBase /

RewriteRule ^old/(.*)$ /new/$1 [R=301,L]

RewriteCond %{QUERY_STRING} ^page=([0-9]+)$
RewriteRule ^article$ /articles/%1? [R=301,L]

RewriteRule ^api/(.*)$ http://127.0.0.1:8080/api/$1 [P,L]

Flags that matter

  • L stops the current round; END stops all rewriting for the request
  • R=301 or R=302 sends an external redirect, changing the URL the client sees
  • P proxies the request through mod_proxy instead of redirecting
  • QSA appends the original query string; a trailing ? in the substitution discards it
  • NC makes matching case-insensitive; use it only when the URL space is truly case-insensitive
  • NE prevents escaping of special characters in the output, which is risky unless intentional

Safety practices

Order specific rules before general ones. Use filesystem conditions such as !-f and !-d only when they express the real intent. Bound capture groups and avoid patterns that match everything. For host or scheme redirects, validate the Host header against an allowlist instead of reflecting it blindly into a Location header.

LogLevel alert rewrite:trace3 shows the exact pattern, input and substitution for each pass. It is the fastest way to find a loop or a context mismatch.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1Why does an apparently valid rule loop?
  2. 2What is the difference between L and END?
  3. 3How do backreferences from RewriteCond differ from RewriteRule captures?
  4. 4How would you safely redirect to the request hostname?

Say it in the interview

I treat rewrite rules as ordered, context-sensitive regex. I anchor patterns, put specific rules first, and choose flags deliberately, because L versus END matters when later rounds can re-trigger a rule. Query string handling is explicit, with QSA or a trailing question mark. I validate with rewrite trace logs and avoid reflecting the Host header unchecked.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Apache mock interview and get scored feedback on depth, clarity and confidence.