gastownhall/beads · error
identity: dial control listener: %w
Error message
identity: dial control listener: %w
What it means
Identify dials the dbproxy control TCP listener to authenticate and fetch the proxy's identity. This error wraps net.DialTimeout's failure — the TCP connection to host:controlPort could not be established.
Source
Thrown at internal/storage/dbproxy/identity/control.go:45
// IdentReply is the authenticated identity published by a managed proxy.
type IdentReply struct {
Schema int `json:"schema"`
Role string `json:"role"`
RootID string `json:"root_id"`
UpstreamID string `json:"upstream_id"`
PID int `json:"pid"`
Birth string `json:"birth"`
DataPort int `json:"data_port"`
ControlPort int `json:"control_port"`
MAC string `json:"mac"`
}
// Identify authenticates to a proxy control listener and returns its identity.
func Identify(host string, controlPort int, secret string, timeout time.Duration) (*IdentReply, error) {
addr := net.JoinHostPort(host, strconv.Itoa(controlPort))
conn, err := net.DialTimeout("tcp", addr, timeout)
if err != nil {
return nil, fmt.Errorf("identity: dial control listener: %w", err)
}
defer func() { _ = conn.Close() }()
if err := conn.SetDeadline(time.Now().Add(timeout)); err != nil {
return nil, fmt.Errorf("identity: set control deadline: %w", err)
}
nonceBytes := make([]byte, identNonceBytes)
if _, err := rand.Read(nonceBytes); err != nil {
return nil, fmt.Errorf("identity: generate request nonce: %w", err)
}
nonce := hex.EncodeToString(nonceBytes)
if _, err := io.WriteString(conn, "IDENT "+secret+" "+nonce+"\n"); err != nil {
return nil, fmt.Errorf("identity: write request: %w", err)
}
line, err := bufio.NewReader(io.LimitReader(conn, maxIdentReplyBytes+1)).ReadString('\n')
if errors.Is(err, io.EOF) && len(line) == 0 {
return nil, ErrIdentRefusedView on GitHub (pinned to 71377f2769)
Solutions
- Verify the proxy control listener is running and note its actual control port
- Confirm host and controlPort match the proxy's startup logs/config
- Test reachability with nc -vz host controlPort
- Check firewall/security-group rules for the control port
Example fix
// before
reply, err := Identify("localhost", 42881, secret, 2*time.Second) // port guess
// after
reply, err := Identify("localhost", proxy.ControlPort(), secret, 5*time.Second) Defensive patterns
Strategy: retry
Validate before calling
conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, strconv.Itoa(controlPort)), timeout)
if err != nil { /* surface actionable message before calling Identify */ } Try / catch
reply, err := Identify(host, port, secret, timeout)
if errors.Is(err, syscall.ECONNREFUSED) || strings.Contains(err.Error(), "dial control listener") {
// wait for the proxy to start and retry with backoff
} Prevention
- Wait for the proxy's ready signal before calling Identify
- Read the control port from the proxy's runtime state, not a hardcoded value
- Verify network/firewall reachability of the control port in CI
When it happens
Trigger: Calling identity.Identify(host, controlPort, secret, timeout) when the control listener is not running, the port is wrong, the host is unreachable, or a firewall blocks the connection.
Common situations: Proxy daemon not started yet; stale/wrong control port from config; connecting from another container/network namespace; DNS resolving to the wrong interface; firewall dropping the port.
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
- identity: write request: %w
- server: DoltServer.Dial: %w
- ensureProxiedServerConfig: pick free port: %w
- allocating ephemeral port: %w
- identity: set control deadline: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/4a285b052f6d8992.
Report an issue: GitHub.