{"record":{"id":"f3082b380135eb06","repo":"ipfs/kubo","slug":"api-not-running","errorCode":null,"errorMessage":"api not running","messagePattern":"api not running","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"info","filePath":"repo/repo.go","lineNumber":18,"sourceCode":"package repo\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\n\tfilestore \"github.com/ipfs/boxo/filestore\"\n\tkeystore \"github.com/ipfs/boxo/keystore\"\n\trcmgr \"github.com/libp2p/go-libp2p/p2p/host/resource-manager\"\n\n\tds \"github.com/ipfs/go-datastore\"\n\tconfig \"github.com/ipfs/kubo/config\"\n\tma \"github.com/multiformats/go-multiaddr\"\n)\n\nvar ErrApiNotRunning = errors.New(\"api not running\") //nolint\n\n// Repo represents all persistent data of a given ipfs node.\ntype Repo interface {\n\t// Config returns the ipfs configuration file from the repo. Changes made\n\t// to the returned config are not automatically persisted.\n\tConfig() (*config.Config, error)\n\n\t// Path is the repo file-system path\n\tPath() string\n\n\t// UserResourceOverrides returns optional user resource overrides for the\n\t// libp2p resource manager.\n\tUserResourceOverrides() (rcmgr.PartialLimitConfig, error)\n\n\t// BackupConfig creates a backup of the current configuration file using\n\t// the given prefix for naming.\n\tBackupConfig(prefix string) (string, error)\n","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/repo/repo.go#L1-L36","documentation":"ErrApiNotRunning is the sentinel error signaling that no Kubo daemon API is reachable at the configured API address. It is declared once in repo/repo.go and returned by fsrepo.APIAddr when the api file does not exist, so callers can distinguish \"daemon not running\" (expected, recoverable) from real failures via errors.Is. cmd/ipfs/kubo/start.go treats it as a non-fatal case, e.g. to start a node without a running daemon.","triggerScenarios":"Calling fsrepo.APIAddr(configRoot) when $IPFS_PATH/api is absent (daemon never started or already stopped), or makeExecutor / RPC clients resolving the API address before `ipfs daemon` is running.","commonSituations":"Running CLI commands expecting a daemon with only an initialized repo, daemon crashed or killed leaving stale repo state, wrong IPFS_PATH pointing at a repo with no api file, or scripts racing daemon startup.","solutions":["Start the daemon first (`ipfs daemon`) before commands that need the API, or use offline mode where supported.","Treat the error as recoverable: compare with errors.Is(err, repo.ErrApiNotRunning) and fall back to local/offline behavior, like start.go does.","Verify IPFS_PATH points at the repo whose daemon is actually running.","For scripts, poll APIAddr until the daemon is up instead of failing on first attempt."],"exampleFix":"// before\napiAddr, err := fsrepo.APIAddr(cfgRoot)\nif err != nil {\n\treturn err\n}\n// after\napiAddr, err := fsrepo.APIAddr(cfgRoot)\nif err != nil {\n\tif errors.Is(err, repo.ErrApiNotRunning) {\n\t\t// run offline / start the daemon\n\t} else {\n\t\treturn err\n\t}\n}","handlingStrategy":"type-guard","validationCode":"// check before calling API-dependent code\napiFile := filepath.Join(os.Getenv(\"IPFS_PATH\"), \"api\")\nif _, err := os.Stat(apiFile); os.IsNotExist(err) {\n\t// daemon not running: start it or use offline mode\n}\n// or probe the endpoint\nif _, err := http.Get(\"http://\" + apiHost + \"/api/v0/id\"); err != nil { /* not running */ }","typeGuard":"func isAPINotRunning(err error) bool {\n\treturn errors.Is(err, repo.ErrApiNotRunning)\n}","tryCatchPattern":"apiAddr, err := fsrepo.APIAddr(cfgRoot)\nswitch {\ncase err == nil:\n\t// use apiAddr\ncase errors.Is(err, repo.ErrApiNotRunning):\n\t// daemon offline: start daemon or proceed offline\ndefault:\n\treturn err\n}","preventionTips":["Always match the sentinel with errors.Is, never string comparison.","Start or health-check the daemon before API-dependent commands.","Confirm IPFS_PATH matches the repo of the running daemon.","Design scripts to poll APIAddr until the daemon is up."],"tags":["daemon","rpc","sentinel-error"],"backgroundTag":"api-not-running","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}