gastownhall/beads · error
timeout waiting for proxy to become ready on %s
Error message
timeout waiting for proxy to become ready on %s
What it means
Returned by spawnAndHandoff when the caller's deadline expires while waiting for the spawned proxy to become ready and the child was killed cleanly. It is the normal (non-hard-timeout) startup-timeout outcome and reports which port the proxy was expected on.
Source
Thrown at internal/storage/dbproxy/proxy/endpoint.go:404
opts.Port, opts.LogFilePath, childErr,
)
}
return Endpoint{}, fmt.Errorf(
"proxy child exited before publishing its OS-assigned port (see %s): %w",
opts.LogFilePath, childErr,
)
case <-hard.C:
if err := killSpawnedChild(child); err != nil {
return Endpoint{}, fmt.Errorf("hard timeout waiting for proxy on %s; safe child kill failed: %w", describeSpawnPort(opts.Port), err)
}
return Endpoint{}, fmt.Errorf("hard timeout (%s) waiting for proxy on %s", spawnReadyHardTimeout, describeSpawnPort(opts.Port))
case <-poll.C:
}
if time.Now().After(deadline) {
if err := killSpawnedChild(child); err != nil {
return Endpoint{}, fmt.Errorf("timeout waiting for proxy on %s; safe child kill failed: %w", describeSpawnPort(opts.Port), err)
}
return Endpoint{}, fmt.Errorf("timeout waiting for proxy to become ready on %s", describeSpawnPort(opts.Port))
}
}
}
// describeSpawnPort renders a requested spawn port for wait/timeout
// messages: 0 is the default OS-assigned path, not a literal "port 0".
func describeSpawnPort(port int) string {
if port == 0 {
return "its OS-assigned port"
}
return fmt.Sprintf("port %d", port)
}
type spawnedProxyChild struct {
cmd *exec.Cmd
done <-chan error
handle *procid.Handle
marker spawnMarkerView on GitHub (pinned to 71377f2769)
Solutions
- Check the child log (opts.LogFilePath) and discovery records under the workspace root for partial startup progress.
- Increase the deadline passed into the open call to reflect actual cold-start cost.
- Retry — after cleanup the next attempt often succeeds faster (warm caches).
- Ensure no other process is interfering (stale locks, antivirus, resource limits) and that the workspace is on local disk where possible.
Example fix
// before: 5s deadline for a 20s cold start ctxDeadline := time.Now().Add(5 * time.Second) // after: derive deadline from observed cold-start time coldStart := 30 * time.Second ctxDeadline := time.Now().Add(coldStart)
Defensive patterns
Strategy: retry
Validate before calling
deadline := time.Now().Add(coldStartBudget) // size budget to your environment
if time.Until(deadline) < minReasonableSpawnWindow {
return errors.New("deadline too short for proxy cold start")
} Try / catch
ep, err := GetCreateDatabaseProxyServerEndpoint(rootDir, opts)
if err != nil && strings.Contains(err.Error(), "timeout waiting for proxy to become ready") {
log.Printf("spawn timed out; child log at %s", opts.LogFilePath)
time.Sleep(time.Second)
ep, err = GetCreateDatabaseProxyServerEndpoint(rootDir, opts)
} Prevention
- Set deadlines from measured cold-start times, not guesses
- Keep the workspace on fast local storage
- Check the child log after every timeout — readiness failure is usually logged there
- Warm caches by reusing a long-lived proxy instead of repeated cold starts
When it happens
Trigger: The poll loop in spawnAndHandoff observes time.Now().After(deadline) before the child publishes a dialable endpoint: backend initialization is slow, the child hangs, or the readiness record is never written.
Common situations: Very large or cold Dolt database; slow/NFS-backed workspace; overloaded machine; caller set an unrealistically short deadline; a wedged dolt subprocess inside the child blocking readiness.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- timeout waiting for proxy on %s; safe child kill failed: %w
- hard timeout waiting for proxy on %s; safe child kill failed
- hard timeout (%s) waiting for proxy on %s
- errIdleTimeout
- dolt sql-server exited before listener became ready
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/8a9cc9f6491f5e5b.
Report an issue: GitHub.