bytebase/bytebase · critical

failed to start embedded PostgreSQL instance

Error message

failed to start embedded PostgreSQL instance

What it means

StartEmbeddedInstance failed while starting the PostgreSQL server process (start, i.e. pg_ctl start) after the data directory was successfully initialized. The underlying error is wrapped with this message; the port may be occupied, binaries may be missing, or the postmaster may have died during startup.

Source

Thrown at backend/resources/postgres/embedded_instance.go:38

type EmbeddedInstanceConfig struct {
	DataDir      string
	Port         int
	User         string
	DatabaseName string
	SeedData     string
}

// StartEmbeddedInstance initializes and starts one embedded PostgreSQL process.
// The returned stopper preserves its data directory.
func StartEmbeddedInstance(ctx context.Context, config EmbeddedInstanceConfig) (func(), error) {
	if config.DataDir == "" || config.Port <= 0 || config.User == "" || config.DatabaseName == "" {
		return nil, errors.New("embedded PostgreSQL instance requires data directory, port, user, and database")
	}
	if err := initDB(config.DataDir, config.User); err != nil {
		return nil, errors.Wrap(err, "failed to initialize embedded PostgreSQL instance")
	}
	if err := start(config.Port, config.DataDir, true); err != nil {
		return nil, errors.Wrap(err, "failed to start embedded PostgreSQL instance")
	}
	stopper := func() {
		if err := stop(config.DataDir); err != nil {
			slog.Error("failed to stop embedded PostgreSQL instance", log.BBError(err))
		}
	}
	if err := setupEmbeddedInstance(ctx, config); err != nil {
		stopper()
		return nil, errors.Wrap(err, "failed to set up embedded PostgreSQL instance")
	}
	return stopper, nil
}

// RemoveEmbeddedInstance stops an embedded PostgreSQL process and removes its
// exact data directory. A missing directory is successful.
func RemoveEmbeddedInstance(dataDir string) error {
	if dataDir == "" {
		return errors.New("embedded PostgreSQL instance requires data directory")

View on GitHub (pinned to 1870550677)

Solutions

  1. Check if the port is occupied (lsof -i :<port> / ss -ltnp) and free it or choose another port.
  2. Remove a stale postmaster.pid from the data directory if no postmaster is running.
  3. Verify postgres/pg_ctl binaries match the data directory's version.
  4. Inspect the PostgreSQL server log in the data directory for the postmaster's failure reason.
  5. Check OS resource limits (shared memory, semaphores) if postmaster dies at startup.

Example fix

// before
config := EmbeddedInstanceConfig{Port: 5432, ...} // occupied
// after
config := EmbeddedInstanceConfig{Port: 5433, ...} // free port, or stop the conflicting instance
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling StartEmbeddedInstance
ln, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", config.Port))
if err != nil { return fmt.Errorf("port %d in use", config.Port) }
ln.Close()
if _, err := exec.LookPath("pg_ctl"); err != nil { return errors.New("pg_ctl not on PATH") }
// remove stale pid file if no process running
os.Remove(filepath.Join(config.DataDir, "postmaster.pid"))

Try / catch

stopper, err := postgres.StartEmbeddedInstance(ctx, cfg)
if err != nil {
    if strings.Contains(err.Error(), "failed to start") {
        // free port, clear stale postmaster.pid, check server log, then retry
    }
    return err
}
defer stopper()

Prevention

When it happens

Trigger: start(config.Port, config.DataDir, true) returns an error in StartEmbeddedInstance — port already in use, pg_ctl/postgres binary missing, data directory corrupted, or postmaster failing to become ready in time.

Common situations: Another PostgreSQL (or the previous run's leftover instance) already listening on the configured port; stale postmaster.pid in the data directory; version mismatch between binaries and initialized data directory; insufficient shared memory/semaphores limits.

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/4039a2f93b1fdd01. Report an issue: GitHub.