Labels are not normalized (lowercase) to matching address name

1. The problem I’m having:

I’m serving a lot of sites and I tried to simplify things by using {labels.*} for the paths since everything follows the same path structure:

(default) {
	root /srv/www/{labels.1}.{labels.0}/{labels.2}/html
	file_server
}

hi.theory.org {
    import default
}

So, a request for hi.theory.org will result in files being served from /srv/www/theory.org/hi/html. This all works fine until I get a request for HI.THEORY.ORG. I’m guessing the path ends up being /srv/www/THEORY.ORG/HI/html which results in a 404 on Linux (case-sensitive filesystem).

This was surprising since hostnames aren’t case sensitive. They match the lowercase address in the Caddyfile. Is there a way to get these labels normalized to the lowercase version of the host being used? For example, it looks like the hostname is normalized to lowercase when making cert requests. I love the {labels.*} as they make for a really tight config and I would love to not have to edit every site to use its own hardcoded path.

Another strange thing that’s happening is where the logs go. I have a global log I set at the top and then all sites import a snippet that sets things to log to an access log. When I hard code the root directive, I get the correct page served for HI.THEORY.ORG, but the logs go to the global log instead of the access log. Other 404s (like https://hi.theory.org/nope) end up in the access log. This feels perhaps related as there’s something strange going on with what’s getting matched.

2. Error messages and/or full log output:

$ curl -i https://hi.theory.org/
HTTP/2 200

$ curl -i https://HI.THEORY.ORG/
HTTP/2 404

3. Caddy version:

v2.10.2 h1:g/gTYjGMD0dec+UgMw8SnfmJ3I9+M2TdvoRL/Ovu6U8=

4. How I installed and ran Caddy:

a. System environment:

Using the official Caddy Debian package on Debian 13 (trixie) x86_64 (amd64).

b. Command:

systemctl restart caddy

c. Service/unit/compose file:

The one shipped in the Debian package.

d. My complete Caddy config:

Here is a simplified version of the Caddyfiles I’m using on my main host. I’m running this exact Caddyfile on a different host (where I put hi.theory.org) and it replicates the issue.

{
        admin off
        cert_issuer acme
        email XXX
        log {
                output file /var/log/caddy/caddy-global.json
        }
}

:80 {
        log {
                output file /var/log/caddy/caddy-http-redirect.json
        }
}

(default-log) {
        log {
                output file /var/log/caddy/access.json
        }
}

(default) {
        import default-log
        root /srv/www/{labels.1}.{labels.0}/{labels.2}/html
        file_server
}

hi.theory.org {
        import default
}

mobius.theory.org {
        import default-log
        root /srv/www/html
        file_server
}

5. Links to relevant resources:

It’s true, we don’t lowercase the labels placeholders.

You’re right, we probably could since they come from a case-insensitive value.

But since you’re on a case-sensitive file system, what if the folder name is capitalized/uppercase? If we lowercase the labels placeholders it would work for you by chance.

In this case, I don’t think it’s getting lucky the folders are lowercase, more that the folders are named to match the (expected) normalized value. What’s ultimately tripping me up is the inconsistency around whether the address is treated case-sensitive or not. Right now, it sometimes is sensitive (labels) and sometimes insensitive (address matching, TLS certs). Ultimately, the value is insensitive and I’d like for it always be treated as such.

Two questions:

  1. Is there a way to do what I’m doing? I love being able to have a single place that defines the root for every site. So many of my address blocks look like:
example.com {
    import site-type
}

It’s unreasonable how much joy this brought me when I migrated from Nginx. The config is so clean and clear.

  1. Do you have any insight why logs for hi.theory.org go to access.json but logs for HI.THEORY.ORG go to caddy-global.json?

Thanks for your time. <3

Yeah, I mean, it probably should be lowercased. I will change that.

1 Like

Thank you! Let me know if you’d like me to open a GitHub issue.

No need, I already fixed it: caddyhttp: Normalize (lowercase) {label.N} placeholders · caddyserver/caddy@e0a8f95 · GitHub

2 Likes