ipfs/kubo · error
serveHTTPApi: manet.Listen(%s) failed: %s
Error message
serveHTTPApi: manet.Listen(%s) failed: %s
What it means
After parsing each Addresses.API multiaddr, kubo calls manet.Listen to bind it (unless already covered by an inherited listener); a bind failure (port in use, permission denied, unassigned address) is wrapped in this error.
Source
Thrown at cmd/ipfs/kubo/daemon.go:841
}
listenerAddrs := make(map[string]bool, len(listeners))
for _, listener := range listeners {
listenerAddrs[string(listener.Multiaddr().Bytes())] = true
}
for _, addr := range apiAddrs {
apiMaddr, err := ma.NewMultiaddr(addr)
if err != nil {
return nil, fmt.Errorf("serveHTTPApi: invalid API address: %q (err: %s)", addr, err)
}
if listenerAddrs[string(apiMaddr.Bytes())] {
continue
}
apiLis, err := manet.Listen(apiMaddr)
if err != nil {
return nil, fmt.Errorf("serveHTTPApi: manet.Listen(%s) failed: %s", apiMaddr, err)
}
listenerAddrs[string(apiMaddr.Bytes())] = true
listeners = append(listeners, apiLis)
}
if len(cfg.API.Authorizations) > 0 && len(listeners) > 0 {
fmt.Printf("RPC API access is limited by the rules defined in API.Authorizations\n")
}
for _, listener := range listeners {
// we might have listened to /tcp/0 - let's see what we are listing on
fmt.Printf("RPC API server listening on %s\n", listener.Multiaddr())
// Browsers require TCP with explicit host.
switch listener.Addr().Network() {
case "tcp", "tcp4", "tcp6":
rpc := listener.Addr().String()
// replace catch-all with explicit localhost URL that works in browsersView on GitHub (pinned to 329838acdf)
Solutions
- Kill the stale process holding the port (`lsof -i :5001` or `pkill -f 'ipfs daemon'`)
- Change Addresses.API to a free port, e.g. /ip4/127.0.0.1/tcp/5101
- Avoid binding privileged ports (<1024) or unassigned local IPs
- Verify with `ipfs daemon` on a fresh IPFS_PATH to rule out lock conflicts
Example fix
// before
"Addresses": { "API": ["/ip4/127.0.0.1/tcp/5001"] } // port busy
// after
"Addresses": { "API": ["/ip4/127.0.0.1/tcp/5101"] } Defensive patterns
Strategy: validation
Validate before calling
// probe the port before starting
ln, err := net.Listen("tcp", "127.0.0.1:5001")
if err != nil {
// port in use: pick another port or stop the other daemon
}
ln.Close() Prevention
- Check port availability before launching daemons in CI/Docker
- Use unique IPFS_PATH and non-default ports for parallel daemons
- Kill stale daemons (`pkill -f 'ipfs daemon'`) before restarts
When it happens
Trigger: `ipfs daemon` where an API address cannot be bound: port already in use by another daemon/process, port <1024 without privileges, binding to a nonexistent interface IP.
Common situations: Second daemon on the same machine using default API port 5001; stale daemon still holding the port; Docker/CI port collisions; firewalls or restricted environments blocking bind.
Related errors
- serveHTTPApi: GetConfig() failed: %s
- serveHTTPApi: socket activation failed: %s
- serveHTTPApi: invalid API address: %q (err: %s)
- private networking (swarm.key / LIBP2P_FORCE_PNET) does not
- supernode routing was never fully implemented and has been r
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/3779de08d97f9573.
Report an issue: GitHub.