caddyserver/caddy · error

server %s: logger name must not have a port: %s

Error message

server %s: logger name must not have a port: %s

What it means

In App.Validate, every key of servers.<name>.logs.logger_names must be a host name without a port. Because net.SplitHostPort succeeds on strings like "example.com:8080", such keys are rejected — log customization is keyed by host, not address.

Source

Thrown at modules/caddyhttp/app.go:441

			if err != nil {
				return fmt.Errorf("invalid listener address '%s': %v", addr, err)
			}
			// check that every address in the port range is unique to this server;
			// we do not use <= here because PortRangeSize() adds 1 to EndPort for us
			for i := uint(0); i < listenAddr.PortRangeSize(); i++ {
				addr := caddy.JoinNetworkAddress(listenAddr.Network, listenAddr.Host, strconv.FormatUint(uint64(listenAddr.StartPort+i), 10))
				if sn, ok := lnAddrs[addr]; ok {
					return fmt.Errorf("server %s: listener address repeated: %s (already claimed by server '%s')", srvName, addr, sn)
				}
				lnAddrs[addr] = srvName
			}
		}

		// logger names must not have ports
		if srv.Logs != nil {
			for host := range srv.Logs.LoggerNames {
				if _, _, err := net.SplitHostPort(host); err == nil {
					return fmt.Errorf("server %s: logger name must not have a port: %s", srvName, host)
				}
			}
		}
	}
	return nil
}

func removeTLSALPN(srv *Server, target string) {
	for _, cp := range srv.TLSConnPolicies {
		// the TLSConfig was already provisioned, so... manually remove it
		for i, np := range cp.TLSConfig.NextProtos {
			if np == target {
				cp.TLSConfig.NextProtos = append(cp.TLSConfig.NextProtos[:i], cp.TLSConfig.NextProtos[i+1:]...)
				break
			}
		}
		// remove it from the parent connection policy too, just to keep things tidy
		for i, alpn := range cp.ALPN {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Strip the port: use just the host ("example.com") as the logger_names key
  2. If you need per-port logging, use separate servers and set per-server access logging instead

Example fix

// before
"logs":{"logger_names":{"example.com:443":"web"}}
// after
"logs":{"logger_names":{"example.com":"web"}}
Defensive patterns

Strategy: validation

Validate before calling

for host := range srvCfg.Logs.LoggerNames {
    if _, _, err := net.SplitHostPort(host); err == nil {
        return fmt.Errorf("logger_names key %q must not contain a port", host)
    }
}

Prevention

When it happens

Trigger: Writing a logger_names key that includes a port, e.g. {"example.com:443": "logname"}, typically when copying addresses from the listen array into the logs config.

Common situations: Adapting a Caddyfile where the site address includes a port and pasting it into the access_logs/logger_names JSON; multi-port setups where users assume logs are per-address.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/54e7d0cb23796e0b. Report an issue: GitHub.