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 browsers

View on GitHub (pinned to 329838acdf)

Solutions

  1. Kill the stale process holding the port (`lsof -i :5001` or `pkill -f 'ipfs daemon'`)
  2. Change Addresses.API to a free port, e.g. /ip4/127.0.0.1/tcp/5101
  3. Avoid binding privileged ports (<1024) or unassigned local IPs
  4. 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

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


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/3779de08d97f9573. Report an issue: GitHub.