caddyserver/caddy · error

retrieving current executable permission bits: %v

Error message

retrieving current executable permission bits: %v

What it means

upgradeBuild stat'ed the resolved executable path to capture its permission bits (needed so the replacement binary keeps the same mode) and os.Stat failed — the path returned by os.Executable no longer exists or is inaccessible.

Source

Thrown at cmd/packagesfuncs.go:133

			// package does not exist
			return caddy.ExitCodeFailedStartup, fmt.Errorf("package is not added")
		}
		delete(pluginPkgs, arg)
	}

	return upgradeBuild(pluginPkgs, fl)
}

func upgradeBuild(pluginPkgs map[string]pluginPackage, fl Flags) (int, error) {
	l := caddy.Log()

	thisExecPath, err := os.Executable()
	if err != nil {
		return caddy.ExitCodeFailedStartup, fmt.Errorf("determining current executable path: %v", err)
	}
	thisExecStat, err := os.Stat(thisExecPath)
	if err != nil {
		return caddy.ExitCodeFailedStartup, fmt.Errorf("retrieving current executable permission bits: %v", err)
	}
	if thisExecStat.Mode()&os.ModeSymlink == os.ModeSymlink {
		symSource := thisExecPath
		// we are a symlink; resolve it
		thisExecPath, err = filepath.EvalSymlinks(thisExecPath)
		if err != nil {
			return caddy.ExitCodeFailedStartup, fmt.Errorf("resolving current executable symlink: %v", err)
		}
		l.Info("this executable is a symlink", zap.String("source", symSource), zap.String("target", thisExecPath))
	}
	l.Info("this executable will be replaced", zap.String("path", thisExecPath))

	// build the request URL to download this custom build
	qs := url.Values{
		"os":   {runtime.GOOS},
		"arch": {runtime.GOARCH},
	}
	for _, pkgInfo := range pluginPkgs {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Reinstall the binary to a stable path (official download or xcaddy) so stat succeeds
  2. Ensure no concurrent package-manager operations touch the Caddy binary during upgrade
  3. Check for and clean up stale artifacts like `caddy.tmp`, then retry `caddy upgrade`
Defensive patterns

Strategy: validation

Validate before calling

P=$(command -v caddy); [ -f "$P" ] && [ -x "$P" ] || echo 'caddy binary missing; reinstall before upgrade'

Prevention

When it happens

Trigger: The binary was deleted or moved between os.Executable and os.Stat (e.g. a concurrent package manager operation, or a leftover broken state from a previous failed upgrade); permission changes that make the directory non-traversable.

Common situations: Racing `apt upgrade`/`brew upgrade` while running `caddy upgrade`; containers where the binary lives on an overlay that changed; leftover `.tmp` backup from an earlier interrupted run.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/2000ada74ee03184. Report an issue: GitHub.