block/buzz · critical · anyhow::Error

DB connection failed: {e}

Error message

DB connection failed: {e}

What it means

Fatal boot error: Db::new() could not establish the Postgres writer pool from DATABASE_URL using the configured db_pool_size. Every later subsystem (events, auth, search) depends on this store, so the relay refuses to start. The sqlx error string with the precise cause is appended.

Source

Thrown at crates/buzz-relay/src/main.rs:176

    relay_metrics::install(config.metrics_port, usage_idle_timeout_secs);
    metrics::gauge!("buzz_audit_enabled").set(if config.audit_enabled { 1.0 } else { 0.0 });
    info!(
        port = config.metrics_port,
        idle_timeout_secs = usage_idle_timeout_secs,
        "Prometheus metrics exporter started"
    );

    let db_config = DbConfig {
        database_url: config.database_url.clone(),
        read_database_url: config.read_database_url.clone(),
        replica_read_max_age_ms: config.replica_read_max_age_ms,
        max_connections: config.db_pool_size,
        read_max_connections: config.db_read_pool_size,
        ..DbConfig::default()
    };
    let db = Db::new(&db_config).await.map_err(|e| {
        error!("Failed to connect to Postgres: {e}");
        anyhow::anyhow!("DB connection failed: {e}")
    })?;
    if db.has_read_pool() {
        info!("Postgres connected (writer + lazy read replica pool)");
        // Reader-down at boot must not crash or block the relay; this warn-only
        // ping is the sole boot-time visibility that the replica is unreachable
        // (the lazy pool with min_connections=0 dials nothing until first use).
        db.spawn_read_pool_boot_ping();
    } else {
        info!("Postgres connected");
    }

    let auto_migrate =
        buzz_auto_migrate_enabled(std::env::var("BUZZ_AUTO_MIGRATE").ok().as_deref());
    if auto_migrate {
        db.migrate().await.map_err(|e| {
            error!("Failed to run database migrations: {e}");
            anyhow::anyhow!("Database migration failed: {e}")
        })?;

View on GitHub (pinned to f956e6fe06)

Solutions

  1. Test the exact URL: `psql "$DATABASE_URL" -c 'select 1'`
  2. Start Postgres (e.g. `docker compose up -d postgres`) and retry boot
  3. Fix host/credentials/database name in DATABASE_URL
  4. Check Postgres logs for auth, TLS, or max_connection refusals

Example fix

# before — relay races postgres at boot
services:
  relay:
    depends_on: [postgres]

# after — wait for readiness
services:
  relay:
    depends_on:
      postgres:
        condition: service_healthy
Defensive patterns

Strategy: retry

Validate before calling

# Pre-flight the exact writer URL before starting the relay.
psql "$DATABASE_URL" -c 'select 1' || { echo 'DATABASE_URL unreachable'; exit 1; }

Try / catch

# docker-compose: bounded restarts absorb boot-time DB races
services:
  relay:
    restart: on-failure:5
  postgres:
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "postgres"]

Prevention

When it happens

Trigger: Postgres unreachable (wrong host/port, DNS failure), credentials rejected, DATABASE_URL malformed, target database does not exist, or the server refuses connections (max_connections exhausted, TLS mismatch).

Common situations: docker compose Postgres container not started or still initializing when the relay boots; `just setup` never run locally; rotated DB password not propagated; Kubernetes service name typo; connection budget exhausted by other clients.

Related errors


AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16). Data as JSON: /api/errors/07986330106b83c1. Report an issue: GitHub.