Caddy Won't Use the Correct Upstream IP No Matter What I Put in Caddyfile

1. The problem I’m having:

Caddy will not use localhost for anything but one of my subdomains (Plex). The rest default to using 192.168.0.40 when only one of them actually should (Home Assistant).

2. Error messages and/or full log output:

When trying to connect to the subdomains uptimekuma.mydomain.com and ai.mydomain.com, I get this error for both, even though the localhost (which is 192.168.0.31) is the one hosting the service listening on those subdomain’s ports. It should not be returning this error at all because my Caddyfile points to localhost for ports 3000, 3001, and 32400, but only 32400 (Plex) actually responds correctly from the localhost:

http.log.error  dial tcp 192.168.0.40:3001: connectex: No connection could be made because the target machine actively refused it.   

It is important to note here that even the autosave.json is saying that the upstream dial address for uptimekuma.mydomain.com and ai.mydomain.com is 192.168.0.40, when it should actually be the localhost per my Caddyfile. Something seems is wrong.

3. Caddy version:

v2.9.1 with the latest [caddy-dns/cloudflare] plugin.

4. How I installed and ran Caddy:

a. System environment:

Windows 11 native caddy.exe (24H2) via command prompt, but I’m using a Cloudflared tunnel between Cloudflare and Caddy (see my TLS config in my Caddyfile). My Cloudflare instance has proper DNS records for the tunnel and for each of the CNAME’s for each subdomain. This hasn’t been an issue with any other DNS-related config I’ve done. To be clear, Caddy is not running in a Docker container. The host machine’s IP address is 192.168.0.31, not 192.168.0.40. Plex, which is run off of the host machine, works just fine, but everything else points to 192.168.0.40 when only Home Assistant should (because it’s running off of a different machine with that IP address). Even if I remove the Home Assistant subdomain entry out of my Caddyfile, it still populates 192.168.0.40 for uptimekuma.mydomain.com and ai.mydomain.com for whatever reason.

b. Command:

(I haven’t yet added Caddy to my PATH, because if I can’t fix this, I’ll be using another reverse proxy engine instead).

Caddy.exe run --config Caddyfile

c. Service/unit/compose file:

N/A

d. My complete Caddy config:

I’ve tried setting the trusted_proxies value to the host machine’s IP (192.168.0.31) with no luck either. The same issue persists.

servers{
	trusted_proxies static 192.168.0.0/24
}
plex.mydomain.com {
	encode gzip zstd
	reverse_proxy localhost:32400
	tls {
		dns cloudflare (private API key)
	}
}
ai.mydomain.com {
	encode gzip zstd
	reverse_proxy localhost:3000
	tls {
		dns cloudflare (private API key)
	}
}
uptimekuma.mydomain.com {
	encode gzip zstd
	reverse_proxy localhost:3001
	tls {
		dns cloudflare (private API key)
	}
}
homeassistant.mydomain.com {
	encode gzip zstd
	reverse_proxy 192.168.0.40:8123
	tls {
		dns cloudflare (private API key)
	}
}

5. Links to relevant resources:

N/A

You have a strange one. It’s most likely a network issue, not Caddy, because Caddy just picks up whatever is configured and resolves DNS if it’s a host name.

First, the dns part in the Caddyfile is completely unrelated to the use of Cloudflare tunnel. The config in the Caddyfile is for use of the DNS01 challenge to get TLS certificate.

This tells me you have a rogue caddy.exe running which you aren’t aware of. Caddy doesn’t resolve hostnames in the config except at runtime when it tries to make the call to upstream. Check your process manager for all the running caddy processes.

A rogue exe is a good suggestion, but I’ve been unable to find one or any evidence of one through logs. I’ve never pointed those other services to 192.168.0.40, they’ve always been pointed to localhost, so even if there was a rogue instance of Caddy running, I’m not sure how it could make that association. Caddy’s autosave.json file lists the upstream dial destination to 192.168.0.40 for those services, so I’m not sure it’s the network either because Caddy itself if creating that config.

Totally lost on this one.

Yes, Caddy creates the file, but it also preserves hostnames defind there. It doesn’t resolve them beforehand. My only other guess is that the wrong config file is being used somehow.