URI String Substitution working with 'respond' but not 'redir'

1. Caddy version (caddy version):

v2.4.6 h1:HGkGICFGvyrodcqOOclHKfvJC0qTU7vny/7FhYp9hNw=

2. How I run Caddy:

a. System environment:

macOS 12.1 | Apple Silicon

b. Command:

./caddy start

c. Service/unit/compose file:


d. My complete Caddyfile or JSON config:

http://localhost:8080 {

	@catalog {
		path */catalog/*

	handle @catalog {
		uri replace : ""
		@token path_regexp token (^\/.+\/)(catalog\/.+)

		#respond @token {re.token.2}
        redir @token https://library.org/{re.token.2}

	handle / {
		respond "Hello World"


3. The problem I’m having:

I am trying to implement a redirect with a string substitution.

Existing URL: http://localhost:8080/scottsboro/catalog/scott:1004
Desired URL after Redirect: https://library.org/catalog/scott1004

In short from the original URL, I want to:

  1. Replace the semicolon with empty string
  2. Strip out the first part of the path keeping only catalog/*

My confusion stems from the fact that the above configuration works as intended for the commented out respond line. However, when that same @token is used in the redirect the regex is applied but the semicolon remains.

4. Error messages and/or full log output:


5. What I already tried:

I tried handle_prefix but could not get it to match on */catalog/*.

6. Links to relevant resources:


I think the problem you’re having is that redir has a higher directive order than uri, so redir runs first. See the directive order here:

To get around this, you can use route to override the directive order. You could replace handle with route, or you could wrap the contents of that handle with a nested route – it depends whether you need the handle blocks to implement mutual exclusivity or not.

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.