With this: % cat Caddyfile http://localhost:2019 { file_server browse } % caddy run 2025/06/08 15:17:36.279 INFO using adjacent Caddyfile 2025/06/08 15:17:36.279 INFO adapted config to JSON {"adapter": "caddyfile"} 2025/06/08 15:17:36.279 INFO admin admin endpoint started {"address": "localhost:2019", "enforce_origin": false, "origins": ["//localhost:2019", "//[::1]:2019", "//127.0.0.1:2019"]} 2025/06/08 15:17:36.280 INFO tls.cache.maintenance started background certificate maintenance {"cache": "0xc00037da80"} 2025/06/08 15:17:36.280 WARN http HTTP/2 skipped because it requires TLS {"network": "tcp", "addr": ":2019"} 2025/06/08 15:17:36.280 WARN http HTTP/3 skipped because it requires TLS {"network": "tcp", "addr": ":2019"} 2025/06/08 15:17:36.280 INFO http.log server running {"name": "srv0", "protocols": ["h1", "h2", "h3"]} 2025/06/08 15:17:36.280 INFO autosaved config (load with --resume flag) {"file": "/home/martin/.config/caddy/autosave.json"} 2025/06/08 15:17:36.280 INFO serving initial configuration 2025/06/08 15:17:36.281 INFO tls storage cleaning happened too recently; skipping for now {"storage": "FileStorage:/home/martin/.local/share/caddy", "instance": "cf308ad4-1b49-40a8-aca4-dd95b219400e", "try_again": "2025/06/09 15:17:36.281", "try_again_in": 86399.99999964} 2025/06/08 15:17:36.281 INFO tls finished cleaning storage units 2025/06/08 15:17:39.664 INFO admin.api received request {"method": "GET", "host": "localhost:2019", "uri": "/", "remote_ip": "127.0.0.1", "remote_port": "53406", "headers": {"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"],"Accept-Encoding":["gzip, deflate, br, zstd"],"Accept-Language":["en-IE,en;q=0.5"],"Connection":["keep-alive"],"Priority":["u=0, i"],"Sec-Fetch-Dest":["document"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-Site":["none"],"Sec-Fetch-User":["?1"],"Upgrade-Insecure-Requests":["1"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64; rv:139.0) Gecko/20100101 Firefox/139.0"]}} Going to http://localhost:2019 gives a 404. The reason is that localhost:2019 is also used as an "admin port" by default. Simply using another port or `admin off` fixes it. This is kind of obvious in hindsight, but not being familiar with Caddy this took me quite some time to figure out. I just saw port 2019 referenced somewhere and figured "well, that's a free port on my system, as good as any other". Trying to use the admin port should probably give an error, or at least a big warning.