cloudflare/cloudflared · error

error determining executable path: %w

Error message

error determining executable path: %w

What it means

installLaunchd on macOS wraps os.Executable() failures with "error determining executable path: %w" when installing cloudflared as a launchd service. os.Executable() fails when the OS cannot report the path of the running binary (e.g. the binary was deleted or renamed after start). The plist written for launchd needs this path to point at the correct executable, so install aborts.

Source

Thrown at cmd/cloudflared/macos_service.go:150

	return resolveLibraryPath("Application Support", launchdIdentifier)
}

func installLaunchd(c *cli.Context) error {
	log := logger.CreateLoggerFromContext(c, logger.EnableTerminalLog)

	if isRootUser() {
		log.Info().Msg("Installing cloudflared client as a system launch daemon. " +
			"cloudflared client will run at boot")
	} else {
		log.Info().Msg("Installing cloudflared client as an user launch agent. " +
			"Note that cloudflared client will only run when the user is logged in. " +
			"If you want to run cloudflared client at boot, install with root permission. " +
			"For more information, visit https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/configure-tunnels/local-management/as-a-service/macos/")
	}
	etPath, err := os.Executable()
	if err != nil {
		log.Err(err).Msg("Error determining executable path")
		return fmt.Errorf("error determining executable path: %w", err)
	}
	installPath, err := installPath()
	if err != nil {
		log.Err(err).Msg("Error determining install path")
		return errors.Wrap(err, "Error determining install path")
	}

	var extraArgs []string
	if c.NArg() > 0 {
		// The service has been installed using a token e.g.,
		// $ cloudflared service install <token>
		//
		// Write the token file to a config directory so we can start the
		// daemon with --token-file

		// Don't use :=, if we did so we would create a new err variable and
		// shadow the outer one, causing the defer below to not have access to
		// the outer err

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Copy the cloudflared binary to a stable location (e.g. /usr/local/bin/cloudflared or /opt/homebrew/bin) and run the install from there
  2. Do not delete, move, or overwrite the binary while the install command is running
  3. Re-download/reinstall the binary if it is corrupted or missing, then retry the install
  4. Check the wrapped error (%w) in the log output for the underlying OS reason and address it specifically

Example fix

// before (fragile)
cd ~/Downloads && sudo ./cloudflared service install
rm ~/Downloads/cloudflared  # binary gone after start => error

// after
sudo cp ~/Downloads/cloudflared /usr/local/bin/cloudflared
sudo /usr/local/bin/cloudflared service install
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: verify the binary location is stable before installing
if _, err := os.Stat(os.Args[0]); err != nil {
    return fmt.Errorf("binary no longer at start path; copy to a stable location first: %w", err)
}

Type guard

func executableOK() bool { p, err := os.Executable(); return err == nil && p != "" }

Try / catch

if err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) {
        log.Printf("binary missing at %s; reinstall to a stable path", pe.Path)
    }
    return fmt.Errorf("error determining executable path: %w", err)
}

Prevention

When it happens

Trigger: Running `cloudflared service install` (macOS) when os.Executable() returns an error: the running binary was deleted or moved after process start, the binary is running from a deleted temp/download directory, or on exotic setups (e.g. overwriting the binary in place during an upgrade) where the OS lookup (proc_pidpath / sysctl) fails.

Common situations: Users who download cloudflared to ~/Downloads, run `sudo ./cloudflared service install`, then their cleanup tool deletes the download; installing from a binary inside a removed tmp dir; upgrade scripts that replace the file between process start and install.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/4c896ee9cd49b9e6. Report an issue: GitHub.