ipfs/kubo · error

unsupported API address: %s

Error message

unsupported API address: %s

What it means

After resolving the API multiaddr, makeExecutor inspects its network type via manet.DialArgs and only supports tcp/tcp4/tcp6 and unix transports for the HTTP RPC client. Any other multiaddr protocol (e.g. ipfs/p2p, ws, quic) reaches the default branch and fails with 'unsupported API address: <multiaddr>'.

Source

Thrown at cmd/ipfs/kubo/start.go:351

	var tpt http.RoundTripper
	switch network {
	case "tcp", "tcp4", "tcp6":
		tpt = http.DefaultTransport
		// RPC over HTTPS requires explicit schema in the address passed to cmdhttp.NewClient
		httpAddr := apiAddr.String()
		if !strings.HasPrefix(host, "http:") && !strings.HasPrefix(host, "https:") && (strings.Contains(httpAddr, "/https") || strings.Contains(httpAddr, "/tls/http")) {
			host = "https://" + host
		}
	case "unix":
		path := host
		host = "unix"
		tpt = &http.Transport{
			DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
				return net.Dial("unix", path)
			},
		}
	default:
		return nil, fmt.Errorf("unsupported API address: %s", apiAddr)
	}

	apiAuth, specified := req.Options[corecmds.ApiAuthOption].(string)
	if specified {
		authorization := config.ConvertAuthSecret(apiAuth)
		tpt = auth.NewAuthorizedRoundTripper(authorization, tpt)
	}

	httpClient := &http.Client{
		Transport: otelhttp.NewTransport(tpt),
	}
	opts = append(opts, cmdhttp.ClientWithHTTPClient(httpClient))

	// Fetch remove version, as some feature compatibility might change depending on it.
	remoteVersion, err := getRemoteVersion(tracingWrappedExecutor{cmdhttp.NewClient(host, opts...)})
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Use a plain TCP multiaddr for --api, e.g. `--api /ip4/127.0.0.1/tcp/5001` or `/dns4/host/tcp/5001` (add /https or /tls/http if TLS is used).
  2. For unix sockets use `--api /unix/path/to/socket`.
  3. Check the daemon's actual API address with `ipfs config Addresses.API` on the daemon host and use that value.

Example fix

# before
ipfs --api /ip4/127.0.0.1/udp/5001/quic-v1 id
# after
ipfs --api /ip4/127.0.0.1/tcp/5001 id
Defensive patterns

Strategy: validation

Validate before calling

addr, err := ma.NewMultiaddr(apiStr)
if err == nil {
    switch _, _, err := manet.DialArgs(addr); {
    case err != nil:
        return fmt.Errorf("bad api addr: %w", err)
    default:
        // ok: tcp or unix transports only
    }
}

Type guard

func isSupportedAPIAddr(addr ma.Multiaddr) bool {
    network, _, err := manet.DialArgs(addr)
    return err == nil && (strings.HasPrefix(network, "tcp") || network == "unix")
}

Prevention

When it happens

Trigger: Setting `--api` (or Addresses.API / the api file) to a multiaddr whose transport is not tcp or unix, e.g. `--api /dns4/example.com/tcp/5001/ws`, `/ip4/1.2.3.4/udp/5001/quic-v1`, or a `/p2p-circuit/...` address.

Common situations: Copying a swarm listening address (quic/websocket) from `ipfs id` into --api instead of the RPC address from Addresses.API; trying to point the CLI at a gateway address over ws; hand-editing the api file with a websocket multiaddr.

Related errors


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