gastownhall/beads · error
dolt sql-server exited immediately on port %d (attempt %d/%d
Error message
dolt sql-server exited immediately on port %d (attempt %d/%d)
What it means
Start() sleeps 200ms after spawning dolt sql-server and checks isProcessAlive(pid). A process that dies within that window almost always failed to bind its port (bind failure), so Start records 'dolt sql-server exited immediately on port %d (attempt %d/%d)' as lastErr and retries or breaks depending on whether the port was explicit.
Source
Thrown at internal/doltserver/doltserver.go:1452
// restarted. os/exec does not close those; mark them first.
sanitizeInheritedFDs()
if startErr := cmd.Start(); startErr != nil {
lastErr = startErr
if !explicitPort {
continue // retry with a new ephemeral port
}
break
}
pid = cmd.Process.Pid
_ = cmd.Process.Release()
// Quick check: did the process exit immediately (bind failure)?
// Give it a moment to fail on port bind before proceeding.
time.Sleep(200 * time.Millisecond)
if !isProcessAlive(pid) {
lastErr = fmt.Errorf("dolt sql-server exited immediately on port %d (attempt %d/%d)", actualPort, i+1, attempts)
pid = 0
if !explicitPort {
continue
}
break
}
lastErr = nil
break
}
_ = logFile.Close()
if lastErr != nil {
// GH#3290 / bd-6dnrw.6: unclean-shutdown manifest corruption is
// detected here but never auto-repaired — reinitializing .dolt is
// destructive, so repair stays behind explicit bd doctor --fix.
if dirs, detErr := detectCorruptManifest(beadsDir, doltDir); detErr == nil && len(dirs) > 0 {
return nil, fmt.Errorf("failed to start dolt server after %d attempts: %w\n"+View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the server log (path printed by the final wrapped error) for the child's actual exit reason.
- Free the port: find the holder with ss -ltnp / lsof -i :PORT and stop it, or pick another port.
- Run bd doctor --fix if the final error mentions corrupt manifest (GH#3290).
- Retry with port 0 (ephemeral) so the OS allocates a fresh port per attempt.
Example fix
// before BD_PORT=4141 bd start // error: exited immediately on port 4141 // after: check logs and free the port, or BD_PORT=0 bd start
Defensive patterns
Strategy: retry
Validate before calling
// check the port is bindable and no orphan dolt is running
const inUse = await new Promise(res => {
const s = require('net').createServer();
s.once('error', () => res(true)); s.listen(port, () => { s.close(); res(false); });
});
if (inUse) console.warn(`port ${port} already in use`); Type guard
null
Try / catch
try {
await bdStart();
} catch (e) {
if (/exited immediately on port/.test(e.message)) {
await checkLogFile(); // find real exit reason
await killOrphanedDolt();
await retryWithEphemeralPort();
}
throw e;
} Prevention
- Use ephemeral ports (port 0) to avoid TOCTOU bind races.
- Clean up orphaned dolt sql-server processes after crashes.
- Keep the managed config valid — don't hand-edit dolt-server.yaml.
- Run bd doctor if starts keep failing.
When it happens
Trigger: Child dolt sql-server exits before the 200ms aliveness check — usually 'address already in use' bind failure, but also invalid config or data-dir corruption causing instant exit.
Common situations: Another process bound the explicit port between allocation and bind (TOCTOU); orphaned dolt sql-server still holding the port; malformed managed config YAML; corrupt .dolt manifest crashing the server at boot.
Related errors
- cannot start dolt server on port %d: %w
- failed to start dolt server after %d attempts: %w Check logs
- start database server: %w
- multiple .doltcfg directories detected
- pidfile: invalid pid
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/b4ed52e4b03c44bd.
Report an issue: GitHub.