chenhg5/cc-connect · error

probe exec failed: %w (stderr: %s)

Error message

probe exec failed: %w (stderr: %s)

What it means

RunIsolationProbe (core/runas_audit.go:210) fails when the probe command itself cannot be executed — cmd.Run() returns an error before/while producing output (binary missing, exec format error, permission problem, non-zero probe exit). Any parseable stdout is still attached to the report, and the raw error plus stderr are wrapped into this message.

Source

Thrown at core/runas_audit.go:210

		shellQuote(cfg.Supervisor),
	)
	fullScript := append([]byte(header), script...)

	// We invoke `sudo -n -iu <user> -- /bin/sh -s` and pipe the script on
	// stdin. Using -s + stdin avoids argv-length limits and avoids ever
	// putting the script body on the command line.
	cmd := exec.CommandContext(probeCtx, "sudo",
		"-n", "-iu", cfg.RunAsUser, "--", "/bin/sh", "-s")
	cmd.Stdin = bytes.NewReader(fullScript)
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		// Still try to parse anything that made it out. Return the err
		// so callers can tell the probe didn't complete cleanly.
		report.RawOutput = stdout.String()
		parseProbeOutput(&report, stdout.String())
		return report, fmt.Errorf("probe exec failed: %w (stderr: %s)", err, strings.TrimSpace(stderr.String()))
	}
	parseProbeOutput(&report, stdout.String())
	report.Fatal = computeAuditFatal(report)
	// RawOutput bloats the on-disk report — only keep it when something
	// went wrong so an operator can inspect what the probe actually saw.
	if report.HasFatal() {
		report.RawOutput = stdout.String()
	}
	return report, nil
}

// parseProbeOutput fills report in place. Unknown tags are ignored for
// forward compatibility with newer probe scripts.
func parseProbeOutput(report *IsolationReport, out string) {
	scanner := bufio.NewScanner(strings.NewReader(out))
	scanner.Buffer(make([]byte, 64*1024), 1024*1024)
	for scanner.Scan() {
		line := scanner.Text()

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Read the stderr embedded in the error to identify the exec failure (not found / permission / exit code)
  2. Build or install the isolation probe binary (rebuild the project so the probe is present)
  3. Check the probe path's permissions (chmod +x) and that it matches the platform/arch
  4. Run the probe manually with the same arguments to reproduce and debug
  5. If the probe exited non-zero by design, inspect the parsed report (report.RawOutput) for the audit findings it did emit

Example fix

// before: probe missing
_, err := RunIsolationProbe(ctx) // probe exec failed: fork/exec /usr/local/lib/cc-connect/probe: no such file or directory
// after: rebuild to install the probe, then re-run
// make build && cc-connect doctor
Defensive patterns

Strategy: fallback

Validate before calling

probePath := "/usr/local/lib/cc-connect/probe"
if fi, err := os.Stat(probePath); err != nil || fi.IsDir() || fi.Mode()&0o111 == 0 {
	return fmt.Errorf("probe missing or not executable at %s — rebuild the project", probePath)
}

Try / catch

report, err := core.RunIsolationProbe(ctx)
if err != nil {
	log.Warn("probe did not complete cleanly; using partial report", "err", err)
	if report != nil && len(report.Fatal) > 0 { /* still surface parsed findings */ }
	return err
}

Prevention

When it happens

Trigger: The audit probe binary doesn't exist at the expected path, lacks execute permission, was built for another platform/arch, crashes, or exits non-zero. Raised via runDoctorOne or the doctor's anonymous goroutine.

Common situations: Probe not built/installed after checkout (missing make step); PATH differences under systemd vs interactive shell; running the doctor on a machine with a different architecture; probe crashing due to missing runtime deps.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/a347b72efdfa7eeb. Report an issue: GitHub.