gastownhall/beads · critical

server: DoltServer.Start: spawn dolt: %w

Error message

server: DoltServer.Start: spawn dolt: %w

What it means

Start() failed to spawn the managed `dolt sql-server --config <path>` child process (exec.Cmd.Start returned an error). The server state is rolled back and the lock released; the dolt binary was never launched.

Source

Thrown at internal/storage/dbproxy/server/doltserver.go:265

	s.cancel = cancel

	cmd := exec.CommandContext(managedCtx, s.doltBinExec, args...)
	cmd.Dir = s.rootDir
	cmd.Stdin = nil
	if s.logFile != nil {
		cmd.Stdout = s.logFile
		cmd.Stderr = s.logFile
	}

	// The proxied server runs CALL DOLT_PUSH/FETCH in-process; see
	// doltserver.ServerSpawnEnv for the guards it needs (GH#4272).
	cmd.Env = doltserver.ServerSpawnEnv()

	if err := cmd.Start(); err != nil {
		s.eg, s.egCtx, s.cancel = nil, nil, nil
		cancel()
		lock.Unlock()
		return fmt.Errorf("server: DoltServer.Start: spawn dolt: %w", err)
	}

	s.pid = cmd.Process.Pid
	birth, err := procid.Capture(s.pid)
	if err != nil {
		_ = cmd.Process.Kill()
		_, _ = cmd.Process.Wait()
		s.eg, s.egCtx, s.cancel, s.pid = nil, nil, nil, 0
		cancel()
		lock.Unlock()
		return fmt.Errorf("server: DoltServer.Start: capture child birth identity: %w", err)
	}
	rootID, err := identity.RootID(s.rootDir)
	if err != nil {
		_ = cmd.Process.Kill()
		_, _ = cmd.Process.Wait()
		s.eg, s.egCtx, s.cancel, s.pid = nil, nil, nil, 0
		cancel()

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify the dolt binary path is correct and executable: run `<path-to-dolt> version` manually.
  2. Check rootDir exists and is accessible (cd into it).
  3. Check ulimit -u / PID limits and disk space; fix resource constraints.
  4. Ensure the binary matches the OS/architecture (e.g. not an arm64 binary on x86_64).

Example fix

// before
srv, _ := server.NewDoltServer("dolt", dir, cfgPath, "", 0, db) // relies on PATH
// after
bin, err := exec.LookPath("dolt")
if err != nil {
    log.Fatal("dolt binary not found: install dolt and ensure it is on PATH")
}
srv, _ := server.NewDoltServer(bin, dir, cfgPath, "", 0, db)
Defensive patterns

Strategy: validation

Validate before calling

bin, err := exec.LookPath(doltBin)
if err != nil {
    return fmt.Errorf("dolt binary %q not found: %w", doltBin, err)
}
if info, err := os.Stat(bin); err != nil || info.IsDir() || info.Mode()&0o111 == 0 {
    return fmt.Errorf("dolt binary %q is not executable", bin)
}
if _, err := exec.Command(bin, "version").Output(); err != nil {
    return fmt.Errorf("dolt binary %q cannot run: %w", bin, err)
}

Try / catch

if err := srv.Start(ctx); err != nil {
    if strings.Contains(err.Error(), "spawn dolt") {
        return fmt.Errorf("failed to launch dolt (check DOLT binary path/permissions): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: cmd.Start() fails at doltserver.go:261 — typically because doltBinExec does not exist or is not executable, the working directory (rootDir) is missing, or fork/exec fails due to resource limits.

Common situations: Dolt binary not installed or PATH/env resolution points to a removed path; binary lacks +x permission; wrong architecture binary; container without exec permission on the volume; too many processes (ulimit).

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/bb824c7e2eb7eb21. Report an issue: GitHub.