Match path with at least one character after prefix? i.e. /path/*

1. Caddy version (caddy version):


2. How I run Caddy:

a. System environment:

Ubuntu 18.04.5, created with DigitalOcean Caddy plugin

b. Command:

caddy run


caddy start

c. Service/unit/compose file:


d. My complete Caddyfile or JSON config: {
	redir{uri} 301
} {
	uri strip_suffix /

	handle_path /js_requests/* {
		rewrite * /path/to/js{uri}

	handle_path /dynamic_content/* {
		rewrite * /path/to/content{uri}

	handle {

3. The problem I’m having:


How can I write a handle_path directive with a prefix like /dynamic_content/* that only matches requests with at least one character after the prefix portion of the path?

Using the above Caddyfile, requests to are matching the handle_path /dynamic_content/* directive. The desired behavior is:

  • matches the last handle, and is sent to S3
  • also matches the last handle and is sent to S3
  • matches the handle_path /dynamic_content/* and is sent to*

Further explanation:

I have a website hosted in S3. Most content is served from S3, but certain paths (/js_requests and /dynamic_content in my sample Caddyfile) serve content from another server (

The first path, /js_requests, isn’t super relevant. But for the sake of being thorough:

  • Requests to this path might looks like /js_requests/do_something.js
  • These requests hit my server,, via reverse proxy and return the appropriate JS file
  • Requests to this path return HTML files to be rendered in the browser.
  • Think of these like blog posts, or products in a shop. You might request /dynamic_content/skydiving-101 – this request gets sent to our server that looks up the article called skydiving-101, renders the full HTML page for that article, and serves it.

This is all working fine given the above Caddyfile. The first two handle_path directives do exactly what they’re supposed to do for any paths /dynamic_content/some-article.

The actual problem:

Requests made to the “root” of these paths, i.e., are matched here.

Our websites have a “landing page” for the dynamic content that displays a list of recent entries. Visiting should render this landing page. This landing page exists in S3 as a file called landing_page. Any requests to*, where * is at least one character, should be sent to the server for content lookup.

Currently, if I visit, provided the example Caddyfile, would see a request for /path/to/content/. It’s expecting something else at the end of the path, e.g. some-article, but nothing exists, so it returns a 404. This is expected behavior on the server side, but that particular request should never hit the server in the first place.

I noticed this behavior early on when requesting (with a trailing slash), so I added the uri strip_suffix / directive to just remove all trailing slashes and avoid it. However, for some reason now it seems the /dynamic_content/* path is being matched even for requests directly to

4. Error messages and/or full log output:


5. What I already tried:

As mentioned previously, I thought adding the uri strip_suffix / directive would solve the issue, but it does not.

6. Links to relevant resources:


That’s a very old version! Please upgrade to v2.4.5.

This is not a good idea, because it’s generally useful to request a directory by using a trailing slash. Things might break unexpectedly with this.

You can use the path_regexp matcher instead for this

@js path_regexp js /js_requests/(.*)+
handle @js {
	uri strip_prefix /js_requests

@dynamic path_regexp dynamic /dynamic_content/(.*)+
handle @dynamic {
	uri strip_prefix /dynamic_content

handle {

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