cloudflare/cloudflared · error

error resolving path for service %q: %w

Error message

error resolving path for service %q: %w

What it means

uninstallSystemd iterates over all known systemd service templates and calls ServiceTemplate.ResolvePath() (homedir.Expand on the template path) to determine whether each service file is installed. If expanding the path fails, cloudflared aborts the whole systemd uninstall with this wrapped error. It exists because the uninstall cannot safely decide which service files to remove without knowing their concrete paths.

Source

Thrown at cmd/cloudflared/linux_service.go:473

		err = uninstallSysv(log)
	}

	removeTokenFile(serviceConfigDir, log)

	if err == nil {
		log.Info().Msg("Linux service for cloudflared uninstalled successfully")
	}

	return err
}

func uninstallSystemd(log *zerolog.Logger) error {
	// Get only the installed services
	installedServices := make(map[string]ServiceTemplate)
	for serviceName, serviceTemplate := range systemdAllTemplates {
		path, err := serviceTemplate.ResolvePath()
		if err != nil {
			return fmt.Errorf("error resolving path for service %q: %w", serviceName, err)
		}
		if _, err := os.Stat(path); err == nil {
			installedServices[serviceName] = serviceTemplate
		} else {
			log.Info().Msgf("Service '%s' not installed, skipping its uninstall", serviceName)
		}
	}

	if _, exists := installedServices[cloudflaredService]; exists {
		if err := runCommand("systemctl", "disable", cloudflaredService); err != nil {
			log.Err(err).Msgf("systemctl disable %s error", cloudflaredService)
			return err
		}
		if err := runCommand("systemctl", "stop", cloudflaredService); err != nil {
			log.Err(err).Msgf("systemctl stop %s error", cloudflaredService)
			return err
		}
	}

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Run the uninstall with a valid HOME: `sudo HOME=/root cloudflared service uninstall`
  2. Check `echo $HOME` is set and points to an existing user's directory; fix the environment if empty or bogus
  3. Ensure the invoking user exists in /etc/passwd (getent passwd $(id -u)) so homedir.Expand can resolve '~'
  4. As a workaround, remove the unit files manually: `sudo rm /etc/systemd/system/cloudflared.service` (and any *.service cloudflared variants) then `sudo systemctl daemon-reload`
  5. Read the wrapped (%w) error — it names the exact template path and expansion failure

Example fix

// before: cron-like env without HOME
$ cloudflared service uninstall
// error: error resolving path for service "cloudflared": error resolving path /etc/systemd/system/cloudflared.service: ...
// after
$ sudo HOME=/root cloudflared service uninstall
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight env check before running service uninstall
func ensureUninstallEnv() error {
    if os.Getenv("HOME") == "" {
        return errors.New("HOME is unset; set HOME (e.g. HOME=/root) before running service uninstall")
    }
    if _, err := exec.LookPath("systemctl"); err != nil {
        return errors.New("systemctl not found: not a systemd system")
    }
    return nil
}

Type guard

func homeResolvable() bool {
    home := os.Getenv("HOME")
    if home == "" {
        if u, err := user.Current(); err == nil && u.HomeDir != "" {
            return true
        }
        return false
    }
    return true
}

Prevention

When it happens

Trigger: During `cloudflared service uninstall` on a Linux host with systemd, when homedir.Expand() fails on one of the systemdAllTemplates paths — practically only when the path contains a '~' that cannot be resolved because HOME/username lookup fails (e.g. empty or invalid HOME env, unknown user).

Common situations: Running the uninstall from an environment with no valid HOME set (cron job, systemd unit, container with stripped env); running as a UID that has no passwd entry so user lookup inside homedir.Expand fails; sandboxed environments where os/user lookups are restricted (CGO disabled + unusual NSS setup).

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/5c34851966dd9968. Report an issue: GitHub.