ipfs/kubo · error

command must be run on the daemon: %v

Error message

command must be run on the daemon: %v

What it means

The command requires daemon execution (NoLocal set) but no API address could be found: neither --api was given nor an API file present in the repo (fsrepo.APIAddr returned nil/ErrApiNotRunning). makeExecutor then fails with 'command must be run on the daemon: <path>' because the command cannot run in the client.

Source

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

		}
		return exe, nil
	}

	// Finally, look in the repo for an API file.
	if apiAddr == nil {
		var err error
		apiAddr, err = fsrepo.APIAddr(cctx.ConfigRoot)
		switch err {
		case nil, repo.ErrApiNotRunning:
		default:
			return nil, err
		}
	}

	// Still no api specified? Run it on the client or fail.
	if apiAddr == nil {
		if req.Command.NoLocal {
			return nil, fmt.Errorf("command must be run on the daemon: %v", req.Path)
		}
		return exe, nil
	}

	// Resolve the API addr.
	//
	// Do not replace apiAddr with the resolved addr so that the requested
	// hostname is kept for use in the request's HTTP header.
	_, err = resolveAddr(req.Context, apiAddr)
	if err != nil {
		return nil, err
	}
	network, host, err := manet.DialArgs(apiAddr)
	if err != nil {
		return nil, err
	}

	// Construct the executor.

View on GitHub (pinned to 329838acdf)

Solutions

  1. Start the daemon first: `ipfs daemon` (or `systemctl start ipfs`), then re-run the command.
  2. Pass the daemon's address explicitly: `ipfs --api /ip4/127.0.0.1/tcp/5001 <cmd>`.
  3. Ensure IPFS_PATH points to the same repo the daemon uses (default ~/.ipfs); check the api file exists at $IPFS_PATH/api and matches the running daemon.

Example fix

# before
ipfs add myfile.txt            # daemon not running
# after
ipfs daemon &
ipfs --api /ip4/127.0.0.1/tcp/5001 add myfile.txt
Defensive patterns

Strategy: fallback

Validate before calling

if ! ipfs swarm peers >/dev/null 2>&1; then
  echo "daemon not running; starting it" >&2
  nohup ipfs daemon >/dev/null 2>&1 &
  until ipfs swarm peers >/dev/null 2>&1; do sleep 0.5; done
fi

Type guard

func daemonReachable() bool {
    _, err := os.Stat(filepath.Join(os.Getenv("IPFS_PATH"), "api"))
    return err == nil
}

Try / catch

out, err := run("ipfs", args...)
if err != nil && strings.Contains(out+err.Error(), "must be run on the daemon") {
    startDaemon() // then retry once
    out, err = run("ipfs", args...)
}

Prevention

When it happens

Trigger: Running a NoLocal command (e.g. most repo-mutating commands like `ipfs add`, `ipfs pin`) when no daemon is running and no --api flag is supplied; the repo exists but its API file is missing, stale, or the daemon was not started.

Common situations: Forgetting `ipfs daemon` before running commands on a server; daemon crashed leaving a stale API file (usually yields ErrApiNotRunning path instead); running commands with a different IPFS_PATH than the running daemon's, so the API file isn't found.

Related errors


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