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.

Custom Response Pages

Custom response pages replace HAProxy’s default error pages with your own HTML for any HTTP status code. Pages are scoped per listener (one or many, or all listeners when none are selected) and have a configurable content type (default text/html).

PropertyDescription
Status codeThe HTTP status code this page applies to (e.g. 403, 429, 500, 502, 503)
ListenersSelected listeners, or all when none selected
Content typeMIME type (default text/html; use application/json for API error bodies)
ContentThe page body — HTML/JSON with {{ variable }} template substitutions

Template Variables

All variables are substituted at request time using the live request’s attributes.

VariableDescription
{{ request_id }}HAProxy unique request ID (for support correlation)
{{ waf_unique_id }}Coraza transaction ID (for 403 WAF blocks)
{{ client_ip }}Client IP address
{{ client_port }}Client TCP port
{{ method }}HTTP method (GET, POST, …)
{{ uri }}Full request URI
{{ path }}Request path (without query string)
{{ query }}Query string (without ?)
{{ host }}Host header value
{{ user_agent }}User-Agent header value
{{ referer }}Referer header value
{{ timeout }}Configured timeout (for timeout-generated errors)
{{ timestamp }}Request timestamp
{{ frontend_name }}HAProxy frontend (listener) name
{{ backend_name }}HAProxy backend name
{{ rate_limit_window }}Rate limit window in seconds (for 429 rate limit pages)
{{ rate_limit_duration }}Block duration in seconds (for 429 tarpit pages; 0 when no block duration)
Rate limit pages use 429, not 503

Listener rate limits return 429 Too Many Requests by default (configurable via the rate limit’s response_code). If you previously created a custom 503 page for rate limiting, create a 429 page instead — the 503 page will no longer be served for rate-limited requests.

Preview

Each page row has a Preview action (eye icon) that opens the rendered template in a new browser tab so you can verify the layout and variable substitution before applying.

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: Custom 403 Page

  1. Navigate to Traffic > Redirects & Rewrites > Error Pages
  2. Click Add Page
  3. Status code: 403
  4. Content type: text/html (or application/json for an API error body)
  5. Listeners: all (or select specific listeners)
  6. Paste your HTML template, using {{ request_id }} for support correlation and {{ waf_unique_id }} for WAF-block correlation
  7. Save and Apply
  8. Use the Preview action (eye icon) to open the rendered page in a new tab and verify the layout

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 custom error page:

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

    Expect your custom 403 page with the request_id rendered.

Next Steps