gastownhall/beads · error

Dolt server at %s:%d is unreachable, and bd will not start a

Error message

Dolt server at %s:%d is unreachable, and bd will not start a local server because an external one is configured.

Verify the external server is running and reachable from this host:
  nc -zv %s %d  # or curl %s:%d for an HTTP-style check
  bd dolt status   # detailed external-server check

What it means

EnsureRunningDetailed refuses to start a local server when server mode is External and the configured host is a non-localhost address — starting a per-project local server would be wrong when bd is pointed at a remote/managed instance. When that external server does not respond, this error explains that bd will not auto-start and gives reachability checks (GH#3518).

Source

Thrown at internal/doltserver/doltserver.go:975

	state, err := IsRunning(serverDir)
	if err != nil {
		return 0, false, err
	}
	if state.Running {
		_ = EnsurePortFile(serverDir, state.Port)
		return state.Port, false, nil
	}

	// If the server mode is External (explicit port in metadata.json,
	// shared server mode, etc.), do not start a per-project server —
	// it would conflict with the external one.
	mode := ResolveServerMode(beadsDir)
	if mode == ServerModeExternal {
		cfg := DefaultConfig(beadsDir)
		if host, ok := externalNonLocalhostHost(beadsDir); ok {
			// Configured for a non-localhost external server:
			// "bd dolt start" is not the right advice (GH#3518).
			return 0, false, fmt.Errorf("Dolt server at %s:%d is unreachable, and bd will not "+
				"start a local server because an external one is configured.\n\n"+
				"Verify the external server is running and reachable from this host:\n"+
				"  nc -zv %s %d  # or curl %s:%d for an HTTP-style check\n"+
				"  bd dolt status   # detailed external-server check",
				host, cfg.Port, host, cfg.Port, host, cfg.Port)
		}
		return 0, false, fmt.Errorf("Dolt server is not running on port %d, and auto-start is suppressed "+
			"because the server is externally managed (dolt.auto-start: false or explicit port configured).\n\n"+
			"Start the external server, or enable auto-start to allow bd to manage the server.\n"+
			"  To start manually: bd dolt start\n"+
			"  To check status: bd dolt status", cfg.Port)
	}

	// Defense-in-depth: if dolt.auto-start is explicitly disabled in
	// config.yaml or env, never spawn a server even if the caller
	// somehow reached this point (e.g. stale AutoStart=true in config).
	if IsAutoStartDisabled() {
		cfg := DefaultConfig(beadsDir)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Verify reachability: nc -zv <host> <port> (or curl <host>:<port>)
  2. Run bd dolt status for a detailed external-server check
  3. Start or restart the external Dolt server on the remote host
  4. Correct BEADS_DOLT_SERVER_HOST / BEADS_DOLT_SERVER_PORT (or config.yaml) if they are wrong
  5. If you actually want a local server, remove the external-server configuration (explicit port/shared mode) so auto-start resumes

Example fix

// before: stale host after server migration
export BEADS_DOLT_SERVER_HOST=old-db.internal
// after: correct host, then verify
export BEADS_DOLT_SERVER_HOST=dolt.internal
nc -zv dolt.internal 31145
Defensive patterns

Strategy: validation

Validate before calling

host := os.Getenv("BEADS_DOLT_SERVER_HOST")
port := 31145 // resolved from config
conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, strconv.Itoa(port)), 3*time.Second)
if err != nil {
    return fmt.Errorf("external dolt server %s:%d unreachable: %w", host, port, err)
}
conn.Close()

Type guard

func isExternalServerUnreachable(err error) bool {
    return err != nil && strings.Contains(err.Error(), "will not start a local server because an external one is configured")
}

Try / catch

port, err := doltserver.EnsureRunning(beadsDir)
if err != nil && isExternalServerUnreachable(err) {
    // fall back to a local dev server only if policy allows
    os.Unsetenv("BEADS_DOLT_SERVER_HOST")
    port, err = doltserver.EnsureRunning(beadsDir)
}

Prevention

When it happens

Trigger: EnsureRunning/EnsureRunningDetailed(beadsDir) with ResolveServerMode==ServerModeExternal and externalNonLocalhostHost returns a host, but the TCP probe to host:port fails (server down, wrong host/port, firewall, DNS).

Common situations: Pointing bd at a company-hosted Dolt server that was stopped or migrated, typos in BEADS_DOLT_SERVER_HOST/PORT, security groups or firewalls blocking the port from this machine.

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


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