gastownhall/beads · error
server: DoltServer.Dial: %w
Error message
server: DoltServer.Dial: %w
What it means
DoltServer.Dial dials the running Dolt server over TCP or a Unix socket and wraps any net.Dialer.DialContext failure. It surfaces the OS-level network error (connection refused, no such file, timeout) with the server: DoltServer.Dial prefix.
Source
Thrown at internal/storage/dbproxy/server/doltserver.go:427
return retErr
}
func (s *DoltServer) Running(_ context.Context) bool {
if s.egCtx == nil {
return false
}
return s.egCtx.Err() == nil
}
func (s *DoltServer) Dial(ctx context.Context) (net.Conn, error) {
network, addr := "tcp", net.JoinHostPort(s.config.Host(), strconv.Itoa(s.config.Port()))
if sock := s.config.Socket(); sock != "" {
network, addr = "unix", sock
}
var d net.Dialer
conn, err := d.DialContext(ctx, network, addr)
if err != nil {
return nil, fmt.Errorf("server: DoltServer.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
- Confirm the server is Running and check its actual listening address (config.Port()/Socket()) matches what Dial uses
- Use waitReady with a generous retry/backoff instead of dialing immediately after Start
- For unix sockets, verify the socket file exists (os.Stat) and the path is < 108 chars with correct permissions
- Test connectivity directly: `nc -z localhost <port>` or `nc -U <socket>` to isolate OS-level failures
Example fix
// before
conn, err := server.Dial(ctx)
if err != nil { return err }
// after
err := waitReady(ctx, server, 30*time.Second) // retry dial until server listens
if err != nil { return fmt.Errorf("dolt server never became ready: %w", err) } Defensive patterns
Strategy: retry
Validate before calling
// check reachability before Dial
addr := fmt.Sprintf("%s:%d", host, port)
if sock != "" {
if _, err := os.Stat(sock); err != nil { return fmt.Errorf("socket %s missing: %w", sock, err) }
} else if conn, err := net.DialTimeout("tcp", addr, time.Second); err != nil {
return fmt.Errorf("%s unreachable: %w", addr, err)
} else { conn.Close() } Try / catch
var conn net.Conn
err := retry.Do(func() (err error) {
conn, err = server.Dial(ctx)
return err
}, retry.Delay(200*time.Millisecond), retry.Attempts(10), retry.Context(ctx))
if err != nil { return fmt.Errorf("dolt server not reachable: %w", err) }
defer conn.Close() Prevention
- Always start via waitReady with backoff instead of immediate Dial
- Log the server's effective port/socket at Start and reuse it for Dial
- Keep socket paths short (<108 chars) and in a stable, user-writable directory
- Add a health Dial to readiness probes in containers
When it happens
Trigger: Calling Dial (directly or via waitReady) when the server is not yet listening, the configured port/socket path is wrong, the socket file was deleted, or the context deadline expires before the TCP/socket handshake.
Common situations: Client dialing before the server finished starting (waitReady race), port already reassigned after a crash, socket path mismatch between config and caller, firewall or container network isolation blocking localhost TCP.
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: ExternalDoltServer.Dial: %w
- ensureProxiedServerConfig: pick free port: %w
- identity: dial control listener: %w
- accept: %w
- failed to remove backup: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/9157280305c361eb.
Report an issue: GitHub.