cloudflare/cloudflared · error

error resolving path

Error message

error resolving path %s: %v

What it means

ServiceTemplate.ResolvePath expands '~' in the template's service file path using homedir.Expand and wraps any failure as "error resolving path %s: %v". It is used by launchd (macOS) and systemd (Linux) service install/uninstall to locate the unit/plist file. It fails when the path cannot be expanded, most commonly because the home directory cannot be determined.

Solutions

  1. Ensure the executing user's home directory exists and is resolvable in /etc/passwd (or NSS)
  2. Use `sudo -H` so HOME is preserved and expandable
  3. Check the inner error (%v) — "cannot expand user-specific home dir" means the HOME/user lookup failed
  4. As a workaround, avoid '~' in the resolved service path context by installing as a user with a valid home directory
  5. Set HOME explicitly if running in a stripped-down environment (container/CI): HOME=/root sudo -E cloudflared service install

Example fix

// before (sudo may unset HOME => expand fails)
sudo cloudflared service install

// after
sudo -H cloudflared service install
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: verify home expansion is possible before install
if _, err := homedir.Expand("~/Library/LaunchAgents/x.plist"); err != nil {
    return fmt.Errorf("home dir unresolvable for current user: %w", err)
}

Try / catch

p, err := st.ResolvePath()
if err != nil {
    if strings.Contains(err.Error(), "cannot expand user-specific home dir") {
        return fmt.Errorf("HOME not set or user has no home dir; run with `sudo -H` or set HOME: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling service install/uninstall (or the template's Generate/Remove flows) when the service template path starts with '~' and homedir.Expand fails: HOME/unix user lookup fails (e.g. sudo cleared HOME, non-existent system user, service account without a home dir).

Common situations: Running `sudo cloudflared service install` in an environment where sudo strips $HOME and the user lookup fails; installing from a CI container running as a uid without a passwd entry; systemd installs with '~' paths under unusual users.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at cmd/cloudflared/service_template.go:30

	homedir "github.com/mitchellh/go-homedir"
)

type ServiceTemplate struct {
	Path     string
	Content  string
	FileMode os.FileMode
}

type ServiceTemplateArgs struct {
	Path      string
	ExtraArgs []string
}

func (st *ServiceTemplate) ResolvePath() (string, error) {
	resolvedPath, err := homedir.Expand(st.Path)
	if err != nil {
		return "", fmt.Errorf("error resolving path %s: %v", st.Path, err)
	}
	return resolvedPath, nil
}

func (st *ServiceTemplate) Generate(args *ServiceTemplateArgs) error {
	tmpl, err := template.New(st.Path).Parse(st.Content)
	if err != nil {
		return fmt.Errorf("error generating %s template: %v", st.Path, err)
	}
	resolvedPath, err := st.ResolvePath()
	if err != nil {
		return err
	}
	if _, err = os.Stat(resolvedPath); err == nil {
		return errors.New(serviceAlreadyExistsWarn(resolvedPath))
	}

	var buffer bytes.Buffer

View on GitHub (pinned to 2253eeeb25)