gastownhall/beads · error
stop database server: %w
Error message
stop database server: %w
What it means
After the proxy run loop finishes, ListenAndServe attempts a bounded stop of the embedded Dolt backend via stopBackendBounded (s.Stop with backendStopTimeout). If that stop returns an error, it is wrapped as 'stop database server: %w' and joined with any run error via errors.Join. This signals the backend may still be running or was not shut down cleanly within the timeout.
Source
Thrown at internal/storage/dbproxy/proxy/server.go:347
}
defer func() { _ = pidfile.Remove(p.rootDir, PIDFileName) }()
g, gctx := errgroup.WithContext(ctx)
g.Go(func() error {
<-gctx.Done()
_ = p.listener.Close()
_ = control.Close()
return nil
})
g.Go(func() error { return p.idleWatcher(gctx) })
g.Go(func() error { return p.acceptLoop(gctx) })
runErr := g.Wait()
_ = p.conns.Wait()
p.stats.IncBackendStop()
stopErr := stopBackendBounded(p.server)
if stopErr != nil {
stopErr = fmt.Errorf("stop database server: %w", stopErr)
}
if errors.Is(runErr, errIdleTimeout) || sigReceived.Load() {
runErr = nil
}
return errors.Join(runErr, stopErr)
}
func stopBackendBounded(s server.DatabaseServer) error {
ctx, cancel := context.WithTimeout(context.Background(), backendStopTimeout)
defer cancel()
return s.Stop(ctx)
}
func (p *proxyServer) idleWatcher(ctx context.Context) error {
if p.idleTimeout <= 0 {
<-ctx.Done()
return nil
}View on GitHub (pinned to 71377f2769)
Solutions
- Run 'bd dolt stop' again (or proxy.Shutdown) after a short delay — it will verify/quarantine the leftover backend record.
- Check for a live dolt backend process (ps aux | grep dolt) and stop or kill it if wedged.
- Inspect the wrapped cause after 'stop database server: ' for the concrete Stop failure.
- If the backend is genuinely dead, clear stale control files via the proxy's purge path and restart.
- Increase headroom on the machine (CPU/IO pressure) if the bounded timeout is routinely exceeded.
Example fix
// before
err := proxy.ListenAndServe(...) // returns: stop database server: context deadline exceeded
// after
if err != nil && strings.Contains(err.Error(), "stop database server") {
_ = proxy.Shutdown(rootDir) // verify/quarantine leftover records, then retry start
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: confirm the backend record and process state are sane
pf, err := pidfile.Read(rootDir, server.PIDFileName)
if err == nil && pf != nil {
if alive := processExists(pf.Pid); alive {
// backend currently running; ensure machine headroom for a bounded stop
}
} Try / catch
if err := proxy.ListenAndServe(ctx, ...); err != nil {
if strings.Contains(err.Error(), "stop database server") {
// backend may be left running; run proxy.Shutdown to verify/quarantine, then retry
if sErr := proxy.Shutdown(rootDir); sErr != nil { /* escalate */ }
}
return err
} Prevention
- Avoid SIGKILLing the backend; stop it through bd/proxy.Shutdown
- Keep CPU/IO headroom so the bounded stop timeout is not exceeded
- Re-run Shutdown after any 'stop database server' failure to clean leftovers
- Monitor for wedged dolt processes
When it happens
Trigger: The proxy is shutting down (idle timeout, signal, or listener error) and backend Stop(ctx) fails or exceeds backendStopTimeout — e.g. the dolt backend process is wedged, already exited unexpectedly, or the stop command times out.
Common situations: Backend hung on a long query or fsync during shutdown; backend killed externally moments before proxy stop; resource exhaustion making the bounded stop time out; SIGKILL'd backend leaving Stop to report failure.
Related errors
- dolt directory is required
- dolt binary not found
- dolt path is not executable
- dolt version probe failed
- dolt version output is unparseable
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/8a7c23f1e9c7755e.
Report an issue: GitHub.