Redirects & Rewrites

Overview

Redirects and rewrites are ordered (drag-and-drop priority) request-mutation rules scoped per listener. They run after WAF and before backend routing in the request pipeline.

Redirects

Redirects send the client to a different URL. Each redirect has:

PropertyDescription
NameDisplay name
Listener scopinglistener_ids, listener_id, frontend_match, or global
PriorityDrag-and-drop ordering
SourcePath prefix or regex to match
TargetDestination URL
Typepermanent (301), temporary (307), or regex
CodeHTTP status code

Redirect Types

TypeStatusDescription
permanent301Permanent redirect (cached by browsers)
temporary307Temporary redirect (preserves method)
regex301/307Regex-based redirect with capture groups

Listener Scoping

ScopeDescription
All listenersApply to every listener
Specific listenersApply to selected listener IDs
Frontend matchApply to listeners matching a frontend name pattern

Rewrites

Rewrites modify the request URI without sending a redirect. Each rewrite has:

PropertyDescription
NameDisplay name
Listener scopingSame options as redirects
PriorityDrag-and-drop ordering
Source patternPattern to match in the URI
TargetReplacement string
TypePath rewrite, query rewrite, or full URI
Redirect vs rewrite

A redirect tells the browser to go to a new URL (the URL changes in the address bar). A rewrite changes the URI internally — the browser URL stays the same, but the backend receives a different path.

Response Headers

Response header rules modify headers on the response before it’s sent to the client. Actions:

ActionDescription
setSet a header (overwrite if exists)
overrideOverride an existing header
addAdd a header (append, don’t overwrite)
delDelete a header

Response header rules support:

  • Per-listener and per-backend scoping
  • Optional HAProxy ACL conditions (only apply the header rule when the condition matches)

Custom Response Pages

Custom error pages can be configured for HTTP status codes 403, 429, and 500. Template variables:

VariableDescription
{{ request_id }}HAProxy unique request ID
{{ waf_unique_id }}Coraza transaction ID (for 403 WAF blocks)
{{ rate_limit_window }}Rate limit window in seconds (for 429)
{{ rate_limit_duration }}Block duration (for 429 tarpit)

Step-by-Step: Redirect HTTP to HTTPS

  1. Navigate to Traffic > Redirects & Rewrites
  2. Click Add Redirect
  3. Name: http-to-https
  4. Listener: select your HTTP listener (port 80)
  5. Source: / (match all paths)
  6. Target: https://example.com (your domain)
  7. Type: permanent (301)
  8. Save and Apply
Use 307 for temporary redirects

Use 307 instead of 301 for temporary redirects. 301 is cached aggressively by browsers and search engines. If you’re not sure the redirect is permanent, use 307.

Step-by-Step: Rewrite an API Path

  1. Navigate to Traffic > Redirects & Rewrites > Rewrites
  2. Click Add Rewrite
  3. Name: api-v1-to-v2
  4. Listener: select your listener
  5. Source pattern: /api/v1/
  6. Target: /api/v2/
  7. Type: path rewrite
  8. Save and Apply

Now requests to /api/v1/users are internally rewritten to /api/v2/users without changing the browser URL.

Step-by-Step: Add a Response Header

  1. Navigate to Traffic > Redirects & Rewrites > Response Headers
  2. Click Add Header Rule
  3. Name: security-headers
  4. Action: set
  5. Header: X-Content-Type-Options
  6. Value: nosniff
  7. Scope: all listeners
  8. Save and Apply

Step-by-Step: Custom 403 Page

  1. Navigate to Traffic > Redirects & Rewrites > Error Pages
  2. Select status code: 403
  3. Upload or paste your HTML template
  4. Use {{ request_id }} for support correlation
  5. Save and Apply

Verification

  1. Test a redirect:

    curl -k -v http://localhost/ 2>&1 | grep -i 'location\|301\|307'
  2. Test a rewrite:

    curl -k -v https://localhost/api/v1/users 2>&1 | grep -i 'request'

    The backend should receive /api/v2/users while the client URL shows /api/v1/users.

  3. Test response headers:

    curl -k -sI https://localhost/ | grep -i x-content-type
  4. Test custom error page:

    curl -k https://localhost/forbidden-endpoint

    Expect your custom 403 page with the request_id rendered.

Next Steps