ipfs/kubo · error
serveHTTPApi: %w
Error message
serveHTTPApi: %w
What it means
serveHTTPApi wraps any error from the API listener startup (bind, serve, or listener failure) with the 'serveHTTPApi: ' prefix and aborts daemon startup. It is thrown when any HTTP API listener fails to become ready, detected via the ready/err channel fan-in loop. It indicates the RPC API at Addresses.API could not be started.
Source
Thrown at cmd/ipfs/kubo/daemon.go:930
// This prevents race conditions where external tools (like systemd path units)
// see the file and try to connect before servers can accept connections.
if len(listeners) > 0 {
readyChannels := make([]chan struct{}, len(listeners))
for i, lis := range listeners {
readyChannels[i] = make(chan struct{})
ready := readyChannels[i]
wg.Go(func() {
errc <- corehttp.ServeWithReady(node, manet.NetListener(lis), ready, opts...)
})
}
// Wait for all listeners to be ready or any to fail
for _, ready := range readyChannels {
select {
case <-ready:
// This listener is ready
case err := <-errc:
return nil, fmt.Errorf("serveHTTPApi: %w", err)
}
}
if err := node.Repo.SetAPIAddr(rewriteMaddrToUseLocalhostIfItsAny(listeners[0].Multiaddr())); err != nil {
return nil, fmt.Errorf("serveHTTPApi: SetAPIAddr() failed: %w", err)
}
}
go func() {
wg.Wait()
close(errc)
}()
return errc, nil
}
func rewriteMaddrToUseLocalhostIfItsAny(maddr ma.Multiaddr) ma.Multiaddr {
first, rest := ma.SplitFirst(maddr)View on GitHub (pinned to 329838acdf)
Solutions
- Find what holds the API port: `lsof -i :5001` or `ss -ltnp | grep 5001`, kill the stale `ipfs daemon`, then retry
- Change the API address: `ipfs config Addresses.API /ip4/127.0.0.1/tcp/5101` (use non-default ports when another node exists)
- Check Addresses.API in `ipfs config` for typos or unbindable addresses (wrong interface, privileged port)
- Run the daemon with a fresh IPFS_PATH if the repo's API address file is corrupted
Example fix
// before $ ipfs daemon Error: serveHTTPApi: listen tcp 127.0.0.1:5001: bind: address already in use // after $ ipfs config Addresses.API /ip4/127.0.0.1/tcp/5101 $ ipfs daemon # now serves API on 5101
Defensive patterns
Strategy: validation
Validate before calling
// before starting daemon, check the API port is free if ss -ltn | grep -q ':5001 ' ; then echo "port 5001 in use: kill stale daemon or change Addresses.API"; fi
Try / catch
// wrap daemon start and surface wrapped cause
if err := daemonFunc(...); err != nil {
if strings.HasPrefix(err.Error(), "serveHTTPApi: ") {
log.Fatalf("API listener failed: %v", err) // inspect wrapped error for bind failure
}
} Prevention
- Use non-default ports for any second node (Addresses.API/Addresses.Gateway/Addresses.Swarm)
- pkill -f "ipfs daemon" before test runs to clear stale daemons
- Run daemons with a dedicated IPFS_PATH via mktemp -d
- Verify Addresses.API multiaddr syntax with `ipfs config Addresses.API` before launch
When it happens
Trigger: Calling `ipfs daemon` when an API listener fails: the API port (default 5001) is already in use by another process, the configured Addresses.API multiaddr is invalid or unbindable, or one of the constructed listeners sends an error on errc before signaling ready.
Common situations: A second kubo node started on the same machine with default ports; a stale/zombie daemon still holding port 5001; Docker containers mapping conflicting ports; invalid Addresses.API config from manual editing or orchestration tooling.
Related errors
- serveHTTPGateway: manet.Listen(%s) failed: %s
- 'ipfs id' cannot query information on remote peers without a
- listing keys failed: %w
- ipfs api address could not be found
- cannot get migrations from unknown fetcher type
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/c1801acf90a5c34b.
Report an issue: GitHub.