caddyserver/caddy · error

invalid listener address '%s': %v

Error message

invalid listener address '%s': %v

What it means

App.Validate parses every address in servers.<name>.listen with caddy.ParseNetworkAddress. Addresses must be network/host/port combinations in a supported form (e.g. tcp/udp/unix, host:port, port ranges). An unparseable address fails validation before Caddy starts.

Source

Thrown at modules/caddyhttp/app.go:424

		}
		if srv.ReadHeaderTimeout == 0 {
			srv.ReadHeaderTimeout = defaultReadHeaderTimeout // see #6663
		}
	}
	ctx.Context = oldContext
	return nil
}

// Validate ensures the app's configuration is valid.
func (app *App) Validate() error {
	lnAddrs := make(map[string]string)

	for srvName, srv := range app.Servers {
		// each server must use distinct listener addresses
		for _, addr := range srv.Listen {
			listenAddr, err := caddy.ParseNetworkAddress(addr)
			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)
				}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Use the form [network/]host:port with a valid port (0-65535 or a range like 8080-8090)
  2. Drop any scheme (http://) from listen entries
  3. Validate with `caddy validate` to confirm parsing

Example fix

// before
"listen": ["http://localhost:8080"]
// after
"listen": ["localhost:8080"]
Defensive patterns

Strategy: validation

Validate before calling

for _, a := range srvCfg.Listen {
    if _, err := caddy.ParseNetworkAddress(a); err != nil {
        return fmt.Errorf("listen %q: %w", a, err)
    }
}

Prevention

When it happens

Trigger: A listen string missing a port ("localhost"), a bad port range ("tcp/localhost:99999"), an unknown network prefix, or stray characters like a trailing colon.

Common situations: Hand-edited JSON after adapting from a Caddyfile; forgetting that bare hosts without ports are invalid in the JSON listen array; copy-paste of URLs (scheme://) into listen.

Related errors


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