caddyserver/caddy · error
listen on 127.0.0.1:0: %v; listen on [::1]:0: %v
Error message
listen on 127.0.0.1:0: %v; listen on [::1]:0: %v
What it means
The aggregated error from listenTCPForPingback when both loopback binds fail: first tcp4 on 127.0.0.1:0, then tcp6 on [::1]:0. The message chains both underlying errors. Since port 0 is used (kernel-assigned), conflicts are impossible — failure means listen sockets themselves are unavailable (FD limits, disabled loopback, sandbox policy).
Source
Thrown at cmd/commandfuncs.go:185
}
return caddy.ExitCodeSuccess, nil
}
type tcpListenFunc func(network, address string) (net.Listener, error)
func listenTCPForPingback(listen tcpListenFunc) (net.Listener, error) {
ln, ipv4Err := listen("tcp4", "127.0.0.1:0")
if ipv4Err == nil {
return ln, nil
}
ln, ipv6Err := listen("tcp6", "[::1]:0")
if ipv6Err == nil {
return ln, nil
}
return nil, fmt.Errorf("listen on 127.0.0.1:0: %v; listen on [::1]:0: %v", ipv4Err, ipv6Err)
}
func cmdRun(fl Flags) (int, error) {
caddy.TrapSignals()
// set up buffered logging for early startup
// so that we can hold onto logs until after
// the config is loaded (or fails to load)
// so that we can write the logs to the user's
// configured output. we must be sure to flush
// on any error before the config is loaded.
logger, defaultLogger, logBuffer := caddy.BufferedLog()
undoMaxProcs := setResourceLimits(logger)
defer undoMaxProcs()
// release the local reference to the undo function so it can be GC'd;
// the deferred call above has already captured the actual function value.
undoMaxProcs = nil //nolint:ineffassign,wastedassignView on GitHub (pinned to 50e54ee279)
Solutions
- Raise FD limits (ulimit -n 4096) and retry
- Confirm loopback exists: ip addr show lo
- In containers, use a normal network stack (not --network none)
- Fall back to `caddy run` for foreground operation without the pingback handshake
Example fix
# before caddy start # listen on 127.0.0.1:0: ...; listen on [::1]:0: ... # after ulimit -n 4096 && caddy start
Defensive patterns
Strategy: fallback
Validate before calling
// pre-flight: both loopback families
for _, addr := range []string{"127.0.0.1:0", "[::1]:0"} {
if ln, err := net.Listen("tcp", addr); err == nil { ln.Close(); return nil }
}
return errors.New("loopback listen unavailable — fix networking/ulimit or use `caddy run`") Prevention
- LimitNOFILE=4096 or higher in service units
- Do not run `caddy start` with --network none; use `caddy run` as PID 1 instead
When it happens
Trigger: FD exhaustion (EMFILE) when both binds are attempted; loopback interface down or missing (some minimal containers or network namespaces); security policy (SELinux, seccomp) denying bind; macOS firewall blocking loopback listens in rare configurations.
Common situations: CI containers with harsh ulimits; --network none containers stripped of loopback; hardened hosts denying unprivileged listen sockets.
Related errors
- opening listener for success confirmation: %v
- creating stdin pipe: %v
- dialing confirmation address: %v
- reading envfile flag: %v
- generating random confirmation bytes: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/f71c615fd9e8fe38.
Report an issue: GitHub.