{"record":{"id":"f4f547410ff9bd54","repo":"gastownhall/beads","slug":"listener-not-ready-after-s-w","errorCode":null,"errorMessage":"listener not ready after %s: %w","messagePattern":"listener not ready after (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/server/doltserver.go","lineNumber":335,"sourceCode":"}\n\nfunc (s *DoltServer) waitReady(ctx context.Context) error {\n\tdeadline := time.Now().Add(startReadyTimeout)\n\tfor {\n\t\tif s.egCtx.Err() != nil {\n\t\t\treturn errors.New(\"dolt sql-server exited before listener became ready\")\n\t\t}\n\n\t\tdctx, dcancel := context.WithTimeout(ctx, startReadyDialTimeout)\n\t\tconn, err := s.Dial(dctx)\n\t\tdcancel()\n\t\tif err == nil {\n\t\t\t_ = conn.Close()\n\t\t\treturn nil\n\t\t}\n\n\t\tif time.Now().After(deadline) {\n\t\t\treturn fmt.Errorf(\"listener not ready after %s: %w\", startReadyTimeout, err)\n\t\t}\n\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-s.egCtx.Done():\n\t\t\treturn errors.New(\"dolt sql-server exited before listener became ready\")\n\t\tcase <-time.After(startReadyPollInterval):\n\t\t}\n\t}\n}\n\nfunc (s *DoltServer) Stop(ctx context.Context) error {\n\tgcErr := s.runShutdownGC(ctx)\n\tif gcErr != nil {\n\t\tgcErr = fmt.Errorf(\"server: DoltServer.Stop: %w\", gcErr)\n\t}\n","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/server/doltserver.go#L317-L353","documentation":"waitReady polled the server's listener by dialing it repeatedly; after startReadyTimeout (30s) elapsed without a successful connection, it returns the last dial error wrapped with \"listener not ready after 30s\". Start() then tears the child down and returns this via error 2405.","triggerScenarios":"Every dial (TCP to host:port, or socket) fails for the full 30s window — dolt never bound the listener because it crashed, is misconfigured (wrong host/port/socket in the YAML), or is catastrophically slow to start.","commonSituations":"Config binds to a different host than Dial checks; port already taken by another process so dolt exits; SELinux/firewall blocking local connections; extremely slow disk making dolt's bootstrap exceed 30s.","solutions":["Inspect the server log for the child's fatal output (port in use, config parse error).","Cross-check host/port/socket in the dolt server config YAML against what your client DSN uses.","Free the configured port (kill the conflicting process) or change the port in the config.","Retry on a less loaded system; if starts are consistently >30s, this is a scaling/IO problem to address on the host."],"exampleFix":"// before\n// config.yaml: host: 10.0.0.5, port: 3307  (client dials localhost:3307)\n// after\n// config.yaml: host: 127.0.0.1, port: 3307  — match host/port with client DSN","handlingStrategy":"validation","validationCode":"// Confirm the dolt config's host/port pair is reachable and free.\nh, p := cfgHost(configPath), cfgPort(configPath)\nconn, err := net.DialTimeout(\"tcp\", net.JoinHostPort(h, strconv.Itoa(p)), time.Second)\nif err == nil {\n    conn.Close()\n    return fmt.Errorf(\"something is already listening on %s:%d\", h, p)\n}","typeGuard":null,"tryCatchPattern":"if err := srv.Start(ctx); err != nil && strings.Contains(err.Error(), \"listener not ready after\") {\n    // inspect log file content for the real dial/bind failure, then surface it\n    tail, _ := os.ReadFile(logPath)\n    return fmt.Errorf(\"server not ready: %v; dolt log tail: %s\", err, lastLines(tail, 20))\n}","preventionTips":["Make client DSN host/port exactly match the dolt server config (socket vs TCP).","Reserve the port for the server; pick dynamic ports in tests.","Check firewall/SELinux policies allow local loopback connections.","Always capture dolt's stdout/stderr into a log file for post-mortem."],"tags":["network","timeout","startup"],"backgroundTag":"connection-refused","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}