{"record":{"id":"3c783f7c4f1e30dc","repo":"ipfs/kubo","slug":"servehttpgateway-w","errorCode":null,"errorMessage":"serveHTTPGateway: %w","messagePattern":"serveHTTPGateway: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/ipfs/kubo/daemon.go","lineNumber":1160,"sourceCode":"\t// This prevents race conditions where external tools (like systemd path units)\n\t// see the file and try to connect before servers can accept connections.\n\tif len(listeners) > 0 {\n\t\treadyChannels := make([]chan struct{}, len(listeners))\n\t\tfor i, lis := range listeners {\n\t\t\treadyChannels[i] = make(chan struct{})\n\t\t\tready := readyChannels[i]\n\t\t\twg.Go(func() {\n\t\t\t\terrc <- corehttp.ServeWithReady(node, manet.NetListener(lis), ready, opts...)\n\t\t\t})\n\t\t}\n\n\t\t// Wait for all listeners to be ready or any to fail\n\t\tfor _, ready := range readyChannels {\n\t\t\tselect {\n\t\t\tcase <-ready:\n\t\t\t\t// This listener is ready\n\t\t\tcase err := <-errc:\n\t\t\t\treturn nil, fmt.Errorf(\"serveHTTPGateway: %w\", err)\n\t\t\t}\n\t\t}\n\n\t\taddr, err := manet.ToNetAddr(rewriteMaddrToUseLocalhostIfItsAny(listeners[0].Multiaddr()))\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"serveHTTPGateway: manet.ToNetAddr() failed: %w\", err)\n\t\t}\n\t\tif err := node.Repo.SetGatewayAddr(addr); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"serveHTTPGateway: SetGatewayAddr() failed: %w\", err)\n\t\t}\n\t}\n\n\tgo func() {\n\t\twg.Wait()\n\t\tclose(errc)\n\t}()\n\n\treturn errc, nil","sourceCodeStart":1142,"sourceCodeEnd":1178,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/cmd/ipfs/kubo/daemon.go#L1142-L1178","documentation":"While waiting for all gateway listeners to become ready, serveHTTPGateway selects on each ready channel; if any serving goroutine pushes an error into errc, startup fails fast with this wrapped error. The inner error is whatever made one of the gateway HTTP servers fail (listener accept error, TLS setup, handler panic recovery, node shutdown).","triggerScenarios":"One of the per-listener go routines in errc reports before all readyChannels fire: the underlying net.Listener was closed, Serve returned early (e.g., http.Server error), or the node shut down during startup.","commonSituations":"Multiple gateway addresses configured where one fails at serve time; systemd socket FD closed between TakeListeners and Serve; startup racing with `ipfs shutdown`; TLS listener misconfiguration.","solutions":["Read the wrapped inner error in the message; it names the actual failing listener/server.","Verify all Addresses.Gateway entries are bindable and not shut down by another component (e.g., check that no unit is stopping the daemon concurrently).","If using socket activation, confirm the FD remains open and valid through startup.","Reduce to a single known-good gateway address to isolate which listener fails, then fix that address."],"exampleFix":"// before: diagnose which listener\n\"serveHTTPGateway: accept tcp 0.0.0.0:8080: use of closed network connection\"\n// after: stop the competing closer\n$ systemctl stop ipfs-gateway-socket-old && ipfs daemon","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"errc, err := serveHTTPGateway(req, cctx)\nif err != nil {\n    var inner error\n    if errors.As(err, &inner) || errors.Unwrap(err) != nil {\n        log.Printf(\"gateway listener failed: %v\", errors.Unwrap(err))\n    }\n    return err // fail startup; do not serve partially\n}","preventionTips":["Keep all Addresses.Gateway entries bindable (validate each before start).","Do not shutdown the daemon concurrently with startup scripts.","With socket activation, verify FDs stay open through the whole boot sequence.","Read the wrapped inner error; it names the failing listener."],"tags":["gateway","listener","startup","race"],"backgroundTag":"listener-failed-during-startup","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}