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

  1. Verify the external server is up: `dolt sql-server` status or ps/pgrep for the process
  2. Check the configured address/socket against the server's actual --port/--socket flags
  3. For unix sockets, confirm the client can read/write the socket file path (permissions, same mount namespace)
  4. 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

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


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