Caddy site access log empty

1. The problem I’m having:

UPDATE: Resolved by removing the :80, :443 block

Empty access log file with no entries for site access logs.

Caddy has access to the log file, but the file is empty.
The global log for caddy itself under the same path is fine with entries.

❯ sudo ls -ahl /var/log/caddy
total 24K
drwxr-xr-x 1 caddy caddy   64 Nov 27 13:28 .
drwxrwxr-x 1 root  syslog 496 Nov 27 00:25 ..
-rw------- 1 caddy caddy  24K Nov 27 13:47 caddy_main.log
-rw------- 1 caddy caddy    0 Nov 27 12:50 fyw.fyi_access.log

2. Error messages and/or full log output:

{"level":"info","ts":1764269240.895673,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//localhost:2019","//[::1]:2019","//127.0.0.1:2019"]}
{"level":"info","ts":1764269240.895867,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0xc000599280"}
{"level":"warn","ts":1764269240.8958921,"logger":"tls","msg":"stapling OCSP","error":"no OCSP stapling for [cloudflare origin certificate *.fyw.fyi fyw.fyi]: no URL to issuing certificate"}
{"level":"warn","ts":1764269240.8959174,"logger":"http.auto_https","msg":"server is listening only on the HTTP port, so no automatic HTTPS will be applied to this server","server_name":"srv1","http_port":80}
{"level":"info","ts":1764269240.8959289,"logger":"http.auto_https","msg":"skipping automatic certificate management because one or more matching certificates are already loaded","domain":"*.fyw.fyi","server_name":"srv0"}
{"level":"info","ts":1764269240.8959308,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
{"level":"info","ts":1764269240.8962512,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
{"level":"info","ts":1764269240.8963132,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
{"level":"warn","ts":1764269240.896327,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"warn","ts":1764269240.896329,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
{"level":"info","ts":1764269240.8963308,"logger":"http.log","msg":"server running","name":"srv1","protocols":["h1","h2","h3"]}
{"level":"info","ts":1764269240.8965137,"msg":"autosaved config (load with --resume flag)","file":"/var/lib/caddy/.config/caddy/autosave.json"}
{"level":"info","ts":1764269240.896679,"logger":"tls","msg":"storage cleaning happened too recently; skipping for now","storage":"FileStorage:/var/lib/caddy/.local/share/caddy","instance":"d65ae4b6-f249-4b27-8657-10454122f7d0","try_again":1764355640.896677,"try_again_in":86399.999999753}
{"level":"info","ts":1764269240.8967547,"logger":"tls","msg":"finished cleaning storage units"}

3. Caddy version:

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

4. How I installed and ran Caddy:

a. System environment:

❯ uname -a
Linux hz-12900 6.8.0-85-generic #85-Ubuntu SMP PREEMPT_DYNAMIC Thu Sep 18 15:26:59 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

❯ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04.3 LTS
Release:        24.04
Codename:       noble

Caddy is installed via apt-get install caddy -y with ubuntu official apt sources.

b. Command:

sudo systemctl start caddy

c. Service/unit/compose file:

# caddy.service
#
# For using Caddy with a config file.
#
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
#
# See https://caddyserver.com/docs/install for instructions.
#
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
ReadWritePaths=/var/log/caddy
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target
❯ sudo cat /etc/systemd/system/caddy.service.d/override.conf
[Service]
ReadWritePaths=/var/log/caddy
❯ sudo systemctl status caddy
● caddy.service - Caddy
     Loaded: loaded (/usr/lib/systemd/system/caddy.service; enabled; preset: enabled)
    Drop-In: /etc/systemd/system/caddy.service.d
             └─override.conf
     Active: active (running) since Thu 2025-11-27 13:47:20 EST; 11min ago
       Docs: https://caddyserver.com/docs/
   Main PID: 765382 (caddy)
      Tasks: 28 (limit: 154243)
     Memory: 25.6M (peak: 27.9M)
        CPU: 1.297s
     CGroup: /system.slice/caddy.service
             └─765382 /usr/bin/caddy run --environ --config /etc/caddy/Caddyfile

Nov 27 13:47:20 hz-12900 caddy[765382]: INVOCATION_ID=db5b49f5cbf148d4961e87c25bdd14b7
Nov 27 13:47:20 hz-12900 caddy[765382]: JOURNAL_STREAM=8:1966703
Nov 27 13:47:20 hz-12900 caddy[765382]: SYSTEMD_EXEC_PID=765382
Nov 27 13:47:20 hz-12900 caddy[765382]: MEMORY_PRESSURE_WATCH=/sys/fs/cgroup/system.slice/caddy.service/memory.pressure
Nov 27 13:47:20 hz-12900 caddy[765382]: MEMORY_PRESSURE_WRITE=c29tZSAyMDAwMDAgMjAwMDAwMAA=
Nov 27 13:47:20 hz-12900 caddy[765382]: {"level":"info","ts":1764269240.8942137,"msg":"using config from file","file":"/etc/caddy/C>
Nov 27 13:47:20 hz-12900 caddy[765382]: {"level":"info","ts":1764269240.8951101,"msg":"adapted config to JSON","adapter":"caddyfile>
Nov 27 13:47:20 hz-12900 caddy[765382]: {"level":"info","ts":1764269240.8954606,"msg":"redirected default logger","from":"stderr",">
Nov 27 13:47:20 hz-12900 caddy[765382]: {"level":"info","ts":1764269240.8965476,"msg":"serving initial configuration"}
Nov 27 13:47:20 hz-12900 systemd[1]: Started caddy.service - Caddy.

d. My complete Caddy config:

(tls_fyw) {
	tls /etc/caddy/fullchain.pem /etc/caddy/private.key
}

{
	log {
		output file /var/log/caddy/caddy_main.log {
			roll_size 10MiB
			roll_keep 5
			roll_keep_for 100d
		}
		format json
		level INFO
	}

	metrics {
		per_host
	}
}

(logging) {
	log {
		output file /var/log/caddy/{args[0]}_access.log {
			roll_size 10MiB
			roll_keep 5
			roll_keep_for 100d
		}
		format json
		level INFO
	}
}

*.fyw.fyi {
	import tls_fyw
	import logging fyw.fyi

	@dockge host dockge.fyw.fyi
	handle @dockge {
		reverse_proxy 127.0.0.1:15001
	}

	@wcs host wcs.fyw.fyi
	handle @wcs {
		reverse_proxy 127.0.0.1:18001
	}

	@dash host dash.fyw.fyi
	handle @dash {
		reverse_proxy 127.0.0.1:20001
	}

	handle {
		respond "Not Found: Service not configured." 404
	}
}

:443, :80 {
	respond "Access Denied." 403
}

5. Links to relevant resources:

UPDATE: After doing some more searches, I found out that the :80,:443 block will affact my logging.
After disabling that block, the logging is working perfectly fine. Tho, I’m curious why would this affect the matching for the wildcard block. Is it something related to matching priority? But why are the reverse_proxies matchers working fine?

If you adapt your configs (before and after) to JSON, you can compare. The difference is that when you have a catch-all block like :443 it adds an option "skip_unmapped_hosts": true to the logging config, and that changes the behaviour.

There might be a bug relating to this and wildcard hosts, I need to think about that a bit. But having the catch-all blocks aren’t useful at all in your case anyway so it’s best to remove in any case.

I fixed the bug here:

2 Likes