ipfs/kubo · error · ErrApiNotFound

ipfs api address could not be found

Error message

ipfs api address could not be found

What it means

ErrApiNotFound is the sentinel error returned by NewPathApi when the API file (~/.ipfs/api by default, or $IPFS_PATH/api) does not exist. The api file is written by a running daemon and contains its multiaddress, so a missing file means no local daemon appears to be running or the path root points somewhere else.

Source

Thrown at client/rpc/api.go:39

	iface "github.com/ipfs/kubo/core/coreiface"
	caopts "github.com/ipfs/kubo/core/coreiface/options"
	"github.com/ipfs/kubo/misc/fsutil"
	dagpb "github.com/ipld/go-codec-dagpb"
	_ "github.com/ipld/go-ipld-prime/codec/dagcbor"
	"github.com/ipld/go-ipld-prime/node/basicnode"
	ma "github.com/multiformats/go-multiaddr"
	manet "github.com/multiformats/go-multiaddr/net"
)

const (
	DefaultPathName = ".ipfs"
	DefaultPathRoot = "~/" + DefaultPathName
	DefaultApiFile  = "api"
	EnvDir          = "IPFS_PATH"
)

// ErrApiNotFound if we fail to find a running daemon.
var ErrApiNotFound = errors.New("ipfs api address could not be found")

// HttpApi implements github.com/ipfs/interface-go-ipfs-core/CoreAPI using
// IPFS HTTP API.
//
// For interface docs see
// https://godoc.org/github.com/ipfs/interface-go-ipfs-core#CoreAPI
type HttpApi struct {
	url         string
	httpcli     http.Client
	Headers     http.Header
	applyGlobal func(*requestBuilder)
	ipldDecoder *legacy.Decoder
	versionMu   sync.Mutex
	version     *semver.Version
}

// NewLocalApi tries to construct new HttpApi instance communicating with local
// IPFS daemon

View on GitHub (pinned to 329838acdf)

Solutions

  1. Start the daemon first: run `ipfs daemon` and wait until it prints the API address
  2. Point the client at the daemon explicitly with NewApi(url) or the multiaddress from `$IPFS_PATH/api` instead of path discovery
  3. Ensure IPFS_PATH matches on both daemon and client (env var must be set for both processes)
  4. Verify the api file exists: `cat $(ipfs config Identity.PeerID 2>/dev/null; echo $IPFS_PATH)/api` or `ls ~/.ipfs/api`; use `errors.Is(err, rpc.ErrApiNotFound)` to branch on this case

Example fix

// before
api, err := rpc.NewPathApi() // fails when daemon not running
if err != nil { return err }
// after
api, err := rpc.NewPathApi()
if errors.Is(err, rpc.ErrApiNotFound) {
    return fmt.Errorf("start the daemon first: 'ipfs daemon'")
}
Defensive patterns

Strategy: fallback

Validate before calling

apiFile := filepath.Join(os.Getenv("IPFS_PATH"), "api")
if apiFile == "api" || apiFile == "" { apiFile = filepath.Join(os.Getenv("HOME"), ".ipfs", "api") }
if _, err := os.Stat(apiFile); os.IsNotExist(err) {
    // daemon not running or wrong IPFS_PATH
}

Type guard

func apiAvailable() bool {
    p := os.Getenv("IPFS_PATH")
    if p == "" { p = filepath.Join(os.Getenv("HOME"), ".ipfs") }
    _, err := os.Stat(filepath.Join(p, "api"))
    return err == nil
}

Try / catch

api, err := rpc.NewPathApi()
if errors.Is(err, rpc.ErrApiNotFound) {
    // fall back to spawning the daemon or an explicit address
    api, err = rpc.NewApi("/ip4/127.0.0.1/tcp/5001")
}
if err != nil { return err }

Prevention

When it happens

Trigger: Creating a client with rpc.NewLocalApi() / NewPathApi() while no daemon is running; IPFS_PATH pointing at a directory with no initialized repo or api file; daemon started with a custom repo path but the client using the default path.

Common situations: Scripts that call the RPC client before `ipfs daemon` is started; DAEMON started with IPFS_PATH set but client without it (or vice versa); repo initialized but daemon never started so no api file was written; macOS/Windows users whose repo lives in a non-default location.

Related errors


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