{"record":{"id":"f71c615fd9e8fe38","repo":"caddyserver/caddy","slug":"listen-on-127-0-0-1-0-v-listen-on-1-0-v","errorCode":null,"errorMessage":"listen on 127.0.0.1:0: %v; listen on [::1]:0: %v","messagePattern":"listen on 127\\.0\\.0\\.1:0: (.+?); listen on \\[::1\\]:0: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/commandfuncs.go","lineNumber":185,"sourceCode":"\t}\n\n\treturn caddy.ExitCodeSuccess, nil\n}\n\ntype tcpListenFunc func(network, address string) (net.Listener, error)\n\nfunc listenTCPForPingback(listen tcpListenFunc) (net.Listener, error) {\n\tln, ipv4Err := listen(\"tcp4\", \"127.0.0.1:0\")\n\tif ipv4Err == nil {\n\t\treturn ln, nil\n\t}\n\n\tln, ipv6Err := listen(\"tcp6\", \"[::1]:0\")\n\tif ipv6Err == nil {\n\t\treturn ln, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"listen on 127.0.0.1:0: %v; listen on [::1]:0: %v\", ipv4Err, ipv6Err)\n}\n\nfunc cmdRun(fl Flags) (int, error) {\n\tcaddy.TrapSignals()\n\n\t// set up buffered logging for early startup\n\t// so that we can hold onto logs until after\n\t// the config is loaded (or fails to load)\n\t// so that we can write the logs to the user's\n\t// configured output. we must be sure to flush\n\t// on any error before the config is loaded.\n\tlogger, defaultLogger, logBuffer := caddy.BufferedLog()\n\n\tundoMaxProcs := setResourceLimits(logger)\n\tdefer undoMaxProcs()\n\t// release the local reference to the undo function so it can be GC'd;\n\t// the deferred call above has already captured the actual function value.\n\tundoMaxProcs = nil //nolint:ineffassign,wastedassign","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/cmd/commandfuncs.go#L167-L203","documentation":"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).","triggerScenarios":"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.","commonSituations":"CI containers with harsh ulimits; --network none containers stripped of loopback; hardened hosts denying unprivileged listen sockets.","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"],"exampleFix":"# before\ncaddy start  # listen on 127.0.0.1:0: ...; listen on [::1]:0: ...\n# after\nulimit -n 4096 && caddy start","handlingStrategy":"fallback","validationCode":"// pre-flight: both loopback families\nfor _, addr := range []string{\"127.0.0.1:0\", \"[::1]:0\"} {\n    if ln, err := net.Listen(\"tcp\", addr); err == nil { ln.Close(); return nil }\n}\nreturn errors.New(\"loopback listen unavailable — fix networking/ulimit or use `caddy run`\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["LimitNOFILE=4096 or higher in service units","Do not run `caddy start` with --network none; use `caddy run` as PID 1 instead"],"tags":["cli","caddy-start","network","loopback","resource-limits"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}