ipfs/kubo · error

non-resolvable API endpoint

Error message

non-resolvable API endpoint

What it means

resolveAddr resolves DNS entries in the API multiaddr (e.g. /dns4/, /dns6/) using a 10-second-timeout DNS resolver. If the DNS resolution succeeds at the protocol level but returns zero addresses, it fails with 'non-resolvable API endpoint'. It is raised in resolveAddr, which makeExecutor calls to validate the API address before dialing.

Source

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

		if err != nil {
			return nil, err
		}
		return stopProfilingFunc, nil
	}
	return func() {}, nil
}

func resolveAddr(ctx context.Context, addr ma.Multiaddr) (ma.Multiaddr, error) {
	ctx, cancelFunc := context.WithTimeout(ctx, 10*time.Second)
	defer cancelFunc()

	addrs, err := dnsResolver.Resolve(ctx, addr)
	if err != nil {
		return nil, err
	}

	if len(addrs) == 0 {
		return nil, errors.New("non-resolvable API endpoint")
	}

	return addrs[0], nil
}

type nopWriter struct {
	io.Writer
}

func (nw nopWriter) Close() error {
	return nil
}

func getRemoteVersion(exe cmds.Executor) (*semver.Version, error) {
	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second*30))
	defer cancel()

	req, err := cmds.NewRequest(ctx, []string{"version"}, nil, nil, nil, Root)

View on GitHub (pinned to 329838acdf)

Solutions

  1. Replace the dns4/dns6 multiaddr with a direct IP: `--api /ip4/<addr>/tcp/5001`.
  2. Verify the hostname resolves: `dig somehost A` / `dig somehost AAAA`, and fix DNS or use the other of dns4/dns6.
  3. Check the daemon host's current address (`ipfs config Addresses.API`) and update the api file at $IPFS_PATH/api or the --api flag accordingly.

Example fix

# before
ipfs --api /dns4/old-container/tcp/5001 id
# after
ipfs --api /ip4/127.0.0.1/tcp/5001 id
Defensive patterns

Strategy: retry

Validate before calling

u, _ := ma.NewMultiaddr(apiStr)
if h, err := u.ValueForProtocol(ma.P_DNS4); err == nil {
    if addrs, err := net.LookupHost(h); err != nil || len(addrs) == 0 {
        return fmt.Errorf("api host %q does not resolve", h)
    }
}

Type guard

func apiHostResolves(addr ma.Multiaddr) bool {
    for _, p := range []int{ma.P_DNS, ma.P_DNS4, ma.P_DNS6} {
        if h, err := addr.ValueForProtocol(p); err == nil {
            addrs, err := net.LookupHost(h)
            return err == nil && len(addrs) > 0
        }
    }
    return true // no DNS component
}

Try / catch

out, err := run("ipfs", args...)
if err != nil && strings.Contains(out+err.Error(), "non-resolvable API endpoint") {
    time.Sleep(2 * time.Second) // tolerate transient DNS
    out, err = run("ipfs", args...)
}

Prevention

When it happens

Trigger: Using `--api /dns4/somehost/tcp/5001` (or /dns6) where somehost has no A/AAAA records; a hostname whose DNS records were removed while the api file still references it; DNS returning NXDOMAIN/NODATA that the resolver maps to an empty result set.

Common situations: Pointing --api at a stale hostname after infrastructure changed (container removed, DNS record deleted); typos in the hostname; split-horizon DNS where the record exists publicly but not from the node's resolver; IPv6-only hostname used with /dns4 (or vice versa).

Related errors


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