gastownhall/beads · error

server: DoltServer.Start: capture child birth identity: %w

Error message

server: DoltServer.Start: capture child birth identity: %w

What it means

Start() spawned the dolt child process but failed to capture its "birth identity" via procid.Capture (used to detect PID reuse later). The child is killed and all start state rolled back before the error is returned.

Source

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

	// 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()
		lock.Unlock()
		return fmt.Errorf("server: DoltServer.Start: resolve proxy root identity: %w", err)
	}

	if err := pidfile.Write(s.rootDir, PIDFileName, pidfile.PidFile{
		Pid:    s.pid,
		Port:   s.config.Port(),
		Schema: pidfile.SchemaV2,
		Kind:   pidfile.KindDoltBackend,
		Birth:  string(birth),
		RootID: rootID,

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the server log file (passed to NewDoltServer) for the child's startup errors — an instant exit usually means a bad dolt server config.
  2. Validate the dolt config YAML: run `dolt sql-server --config <configPath>` manually and inspect output.
  3. Verify /proc is mounted and readable (e.g. in Docker, do not use --pid=host restrictions that hide processes).
  4. Retry Start(); transient scheduling races usually disappear on retry.
Defensive patterns

Strategy: retry

Validate before calling

// Ensure /proc is usable so procid.Capture can read process identity.
if _, err := os.Stat(filepath.Join("/proc", "self", "stat")); err != nil {
    return fmt.Errorf("/proc unavailable; process identity capture will fail: %w", err)
}

Try / catch

if err := srv.Start(ctx); err != nil {
    if strings.Contains(err.Error(), "capture child birth identity") {
        // child likely died instantly: check the server log, then retry once
        log.Errorf("dolt exited immediately, see server log: %v", err)
        return retryStart(srv, ctx) // bounded single retry
    }
    return err
}

Prevention

When it happens

Trigger: procid.Capture(s.pid) returns an error immediately after cmd.Start() — the child exited so fast it is already gone (e.g. dolt dies instantly on bad config), or /proc is unreadable (restricted container, non-Linux procfs issues).

Common situations: Dolt crashing immediately at startup (invalid YAML config, port binding failure) so the PID disappears before Capture reads it; hardened containers hiding /proc; heavily loaded systems racing process exit.

Related errors


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