gastownhall/beads · error
server: ExternalDoltServer.Dial: %w
Error message
server: ExternalDoltServer.Dial: %w
What it means
ExternalDoltServer.Dial dials a Dolt server the library did not start (an external dolt sql-server) over TCP or Unix socket, wrapping net.DialContext errors. Identical mechanics to DoltServer.Dial but for externally managed processes.
Source
Thrown at internal/storage/dbproxy/server/external_dolt_server.go:102
func (s *ExternalDoltServer) Stop(_ context.Context) error {
s.started.Store(false)
return nil
}
func (s *ExternalDoltServer) Running(_ context.Context) bool {
return s.started.Load()
}
func (s *ExternalDoltServer) Dial(ctx context.Context) (net.Conn, error) {
network, addr := "tcp", net.JoinHostPort(s.host, strconv.Itoa(s.port))
if s.socket != "" {
network, addr = "unix", s.socket
}
var d net.Dialer
conn, err := d.DialContext(ctx, network, addr)
if err != nil {
return nil, fmt.Errorf("server: ExternalDoltServer.Dial: %w", err)
}
if tc, ok := conn.(*net.TCPConn); ok {
_ = tc.SetKeepAlive(true)
_ = tc.SetKeepAlivePeriod(s.keepAlivePeriod)
}
return conn, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Verify the external server is up: `dolt sql-server` status or ps/pgrep for the process
- Check the configured address/socket against the server's actual --port/--socket flags
- For unix sockets, confirm the client can read/write the socket file path (permissions, same mount namespace)
- Add retry/backoff around Dial to tolerate brief restarts of the external server
Example fix
// before
conn, err := extServer.Dial(ctx)
// after
var conn net.Conn
var derr error
for i := 0; i < 5; i++ {
if conn, derr = extServer.Dial(ctx); derr == nil { break }
select { case <-ctx.Done(): return ctx.Err(); case <-time.After(time.Duration(i+1) * 500 * time.Millisecond): }
} Defensive patterns
Strategy: retry
Validate before calling
// pre-flight the external server
if sock != "" {
if _, err := os.Stat(sock); err != nil { return fmt.Errorf("external socket %s missing", sock) }
} else if c, err := net.DialTimeout("tcp", hostPort, 2*time.Second); err != nil {
return fmt.Errorf("external dolt server %s unreachable: %w", hostPort, err)
} else { c.Close() } Try / catch
conn, err := extServer.Dial(ctx)
if err != nil {
return fmt.Errorf("cannot reach external dolt server (is it running? right address?): %w", err)
}
defer conn.Close() Prevention
- Validate external server host/port/socket config at startup with a probe dial
- Supervise the external dolt sql-server (systemd/k8s) and add Dial retries for restarts
- Use an address reachable from the client's network namespace (avoid bare localhost across containers)
When it happens
Trigger: Dialing an ExternalDoltServer whose host:port or socket was configured incorrectly, the external dolt sql-server is down or restarting, or ctx is cancelled before the dial completes.
Common situations: Stale configuration pointing at a server that was redeployed on another port; external server crashed or was OOM-killed; running in a different container/network namespace so localhost doesn't reach the server; socket file removed by tmpfs cleanup.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- server: DoltServer.Dial: %w
- ensureProxiedServerConfig: pick free port: %w
- accept: %w
- failed to remove backup: %w
- pull: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0f5146b63d70e75b.
Report an issue: GitHub.