ipfs/kubo · warning

finding binary path: %w

Error message

finding binary path: %w

What it means

The binary() collector embeds the running executable itself into the profile archive so dumps are debuggable later. On Linux it resolves /proc/<pid>/exe; on all other GOOS it calls os.Executable(). If os.Executable() fails, the error is wrapped as "finding binary path". It means the runtime could not determine the path of the currently running program.

Source

Thrown at profile/profile.go:232

	return pprof.Lookup("allocs").WriteTo(w, 0)
}

func versionInfo(ctx context.Context, _ Options, w io.Writer) error {
	return json.NewEncoder(w).Encode(version.GetVersionInfo())
}

func binary(ctx context.Context, _ Options, w io.Writer) error {
	var (
		path string
		err  error
	)
	if goos == "linux" {
		pid := os.Getpid()
		path = fmt.Sprintf("/proc/%d/exe", pid)
	} else {
		path, err = os.Executable()
		if err != nil {
			return fmt.Errorf("finding binary path: %w", err)
		}
	}
	fi, err := os.Open(path)
	if err != nil {
		return fmt.Errorf("opening binary %q: %w", path, err)
	}
	_, err = io.Copy(w, fi)
	_ = fi.Close()
	if err != nil {
		return fmt.Errorf("copying binary %q: %w", path, err)
	}
	return nil
}

func mutexProfile(ctx context.Context, opts Options, w io.Writer) error {
	prev := runtime.SetMutexProfileFraction(opts.MutexProfileFraction)
	defer runtime.SetMutexProfileFraction(prev)
	err := waitOrCancel(ctx, opts.ProfileDuration)

View on GitHub (pinned to 329838acdf)

Solutions

  1. Do not delete or rename the running binary before profile collection completes (keep the old file until after WriteProfiles)
  2. Keep the original executable on disk while the process runs; stage upgrades by copying to a new file and swapping via rename after shutdown
  3. On Linux this path is /proc/<pid>/exe and this specific error cannot occur — verify GOOS if you see it there
  4. Provide a pre-recorded binary path fallback if your deployment deletes executables

Example fix

// before
os.Remove(selfPath)      // self-upgrade deletes running binary
WriteProfiles(ctx, p)    // os.Executable() fails: path gone
// after
WriteProfiles(ctx, p)    // collect while binary still exists
os.Remove(oldBinaryPath) // clean up after profiling
Defensive patterns

Strategy: fallback

Validate before calling

if runtime.GOOS != "linux" {
    if _, err := os.Executable(); err != nil {
        log.Printf("binary path unavailable, skipping binary embed: %v", err)
        return skipBinaryCollector
    }
}

Try / catch

if err := WriteProfiles(ctx, p); err != nil {
    var pe *fs.PathError
    if errors.As(errors.Unwrap(err), &pe) && strings.HasPrefix(err.Error(), "finding binary path") {
        log.Printf("no executable path; rerun without the binary collector: %v", pe)
    }
    return err
}

Prevention

When it happens

Trigger: os.Executable() failing on non-Linux platforms: the executable was deleted or renamed while running (common on macOS/darwin and Windows), the process was started via a mechanism that erased the program path, or an OS API failure returning an error from sysctl/GetModuleFileName.

Common situations: Self-upgrading binaries that delete/replace the running executable before calling WriteProfiles; running from an overwritten temp binary; exotic sandbox/container runtimes where the executable path is unavailable.

Related errors


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