ipfs/kubo · error

api flag specified but command cannot be run on the daemon

Error message

api flag specified but command cannot be run on the daemon

What it means

When a command is marked NoRemote it must execute in the CLI client process, but the user also passed --api (or the request implies the daemon), which forces daemon execution. makeExecutor detects this contradiction and fails with 'api flag specified but command cannot be run on the daemon'. The ipfs daemon command itself is exempted from this check.

Source

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

		}
	}

	// Get the API option from the commandline.
	apiAddr, err := apiAddrOption(req)
	if err != nil {
		return nil, err
	}

	// Require that the command be run on the daemon when the API flag is
	// passed (unless we're trying to _run_ the daemon).
	daemonRequested := apiAddr != nil && req.Command != daemonCmd

	// Run this on the client if required.
	if req.Command.NoRemote {
		if daemonRequested {
			// User requested that the command be run on the daemon but we can't.
			// NOTE: We drop this check for the `ipfs daemon` command.
			return nil, errors.New("api flag specified but command cannot be run on the daemon")
		}
		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 {

View on GitHub (pinned to 329838acdf)

Solutions

  1. Remove the `--api` flag for this command so it runs locally in the client process.
  2. If you intended daemon execution, verify the command actually supports remote mode; if not, run it on the machine hosting the repo without --api.
  3. Fix wrapper scripts to only add --api for remote-capable commands instead of unconditionally.

Example fix

# before
ipfs --api /ip4/127.0.0.1/tcp/5001 <no-remote-command>
# after
ipfs <no-remote-command>
Defensive patterns

Strategy: validation

Validate before calling

// in a wrapper script: only add --api for remote-capable commands
if ! case " $NO_REMOTE_CMDS " in *" $cmd "*) true;; *) false;; esac; then
  args=(--api "$IPFS_API" "${args[@]}")
fi

Type guard

func apiFlagAllowed(cmd *cmds.Command) bool {
    return !cmd.NoRemote
}

Try / catch

err := runIPFS(args...)
if err != nil && strings.Contains(err.Error(), "api flag specified but command cannot be run on the daemon") {
    // retry without the --api flag
    args = removeFlag(args, "--api")
    err = runIPFS(args...)
}

Prevention

When it happens

Trigger: Running a NoRemote command (commands that must touch local files/repo directly, e.g. some `ipfs daemon`-adjacent or repo commands) while passing `--api /ip4/.../tcp/5001` on the command line; also IPFS_PATH-based API discovery is bypassed, so only an explicit --api triggers this branch.

Common situations: Shell aliases or scripts that always append `--api $ADDR` to every ipfs call, then hitting a command that forbids remote execution; CI wrappers that set the api flag globally; misunderstanding that --api is merely a hint — for NoRemote commands it is a hard error.

Related errors


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