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
- Use the form [network/]host:port with a valid port (0-65535 or a range like 8080-8090)
- Drop any scheme (http://) from listen entries
- 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
- Use caddy.ParseNetworkAddress (or `caddy validate`) as the single source of truth for address syntax
- Never put schemes (http://) in listen entries; schemes belong in site addresses only
- Prefer the Caddyfile adapter over hand-written JSON listen arrays
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
- server %s: listener address repeated: %s (already claimed by
- parsing listener address: %v
- must be exactly one listener address; cannot listen on: %s
- indexing config: %v
- %s: %s field must be a string or number
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/7e84420e3fdd7a7b.
Report an issue: GitHub.