gastownhall/beads · error

server started (PID ) but not accepting connections on port

Error message

server started (PID %d) but not accepting connections on port %d: %w

%s

What it means

This error is returned by doltserver.Start when the dolt sql-server process spawned successfully (its PID is alive) but waitForReady never observed a MySQL handshake on the bound port within the ready timeout. Before returning, Start kills the process and removes the PID/port files; if the server log contains journal-corruption errors, the generic message is upgraded to include corruptJournalRecoveryHint with recovery steps.

Solutions

  1. Read the server log at the path printed in the error (bd dolt logs / .beads/dolt-server.log) for the underlying startup error
  2. If the message includes the journal-corruption hint, follow it: back up and reinitialize via 'bd doctor --fix' (repair is deliberately not automatic)
  3. Check for a hung dolt process (ps aux | grep dolt sql-server) and kill it before retrying
  4. Increase the readiness timeout (BEADS_DOLT_READY_TIMEOUT) if the database is large but healthy
  5. Verify the container/host has enough memory, CPU, and disk I/O for Dolt startup

Example fix

// before
// error: server started (PID 12345) but not accepting connections on port 41017: timeout...
//   [journal corruption hint follows]
// after
// $ bd doctor --fix   # backs up corrupt db and reinitializes .dolt
// $ bd dolt start
Defensive patterns

Strategy: try-catch

Validate before calling

// Before Start, check for known corruption markers so you can repair proactively
if dirs, detErr := doltserver.DetectCorruptManifestIfAvailable(beadsDir); detErr == nil && len(dirs) > 0 {
    // run: bd doctor --fix  before attempting startup
    fmt.Fprintf(os.Stderr, "corrupt manifest detected in %v; run bd doctor --fix\n", dirs)
}

Try / catch

state, err := doltserver.Start(cfg)
if err != nil {
    var logHint string
    if strings.Contains(err.Error(), "journal") || strings.Contains(err.Error(), "corrupt") {
        // corruption path: run bd doctor --fix, do not blind-retry
        fmt.Fprintln(os.Stderr, "corruption suspected; run: bd doctor --fix")
        os.Exit(1)
    }
    _ = logHint
    return fmt.Errorf("dolt server start failed: %w (check %s)", err, doltserver.LogPath(beadsDir))
}

Prevention

When it happens

Trigger: waitForReady(cfg.Host, actualPort, readyTimeout()) exhausts its deadline — the server process is running but the MySQL engine never starts accepting/greeting connections, e.g. Dolt is stuck initializing a corrupt journal, the log shows corrupt-journal errors, or the server hangs during startup (slow disk, resource starvation).

Common situations: Unclean shutdown (power loss, SIGKILL) leaving a corrupt Dolt journal; a shared multi-tenant server starved of CPU/disk; container resource limits preventing Dolt from finishing startup; very large databases taking longer than the ready timeout to open; server crashing after the initial liveness check but before listening.

Related errors


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

Appendix: source

Thrown at internal/doltserver/doltserver.go:1503

		return nil, fmt.Errorf("writing PID file: %w", err)
	}
	if err := writePortFile(beadsDir, actualPort); err != nil {
		if proc, findErr := os.FindProcess(pid); findErr == nil {
			_ = proc.Kill()
		}
		_ = os.Remove(pidPath(beadsDir))
		return nil, fmt.Errorf("writing port file: %w", err)
	}

	// Wait for server to accept connections
	if err := waitForReady(cfg.Host, actualPort, readyTimeout()); err != nil {
		if proc, findErr := os.FindProcess(pid); findErr == nil {
			_ = proc.Kill()
		}
		_ = os.Remove(pidPath(beadsDir))
		_ = os.Remove(portPath(beadsDir))
		if hasJournalCorruption, logErr := logHasCorruptJournalError(logPath(beadsDir)); logErr == nil && hasJournalCorruption {
			return nil, fmt.Errorf("server started (PID %d) but not accepting connections on port %d: %w\n\n%s",
				pid, actualPort, err, corruptJournalRecoveryHint(beadsDir))
		}
		return nil, fmt.Errorf("server started (PID %d) but not accepting connections on port %d: %w\nCheck logs: %s",
			pid, actualPort, err, logPath(beadsDir))
	}

	return &State{
		Running: true,
		PID:     pid,
		Port:    actualPort,
		DataDir: doltDir,
	}, nil
}

// EnsureGlobalDatabase connects to the shared Dolt server and creates the
// beads_global database if it doesn't already exist. This is idempotent and
// safe to call on every shared server init. Schema initialization and config
// seeding (issue prefix, project ID) are handled by the store layer when the

View on GitHub (pinned to 71377f2769)