{"record":{"id":"371346879db0e5d8","repo":"block/buzz","slug":"audit-db-connection-failed-e","errorCode":null,"errorMessage":"Audit DB connection failed: {e}","messagePattern":"Audit DB connection failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"critical","filePath":"crates/buzz-relay/src/main.rs","lineNumber":361,"sourceCode":"            }\n        }\n    }\n\n    // NIP-33: backfill d_tag for any existing parameterized replaceable events\n    // that predate the column addition. Idempotent — no-ops when fully populated.\n    match db.backfill_d_tags().await {\n        Ok(0) => {}\n        Ok(n) => info!(\"Backfilled d_tag for {n} NIP-33 events\"),\n        Err(e) => error!(\"Failed to backfill d_tags: {e}\"),\n    }\n\n    let audit = if config.audit_enabled {\n        let audit_pool = sqlx::postgres::PgPoolOptions::new()\n            .max_connections(5)\n            .min_connections(1)\n            .connect(&config.database_url)\n            .await\n            .map_err(|e| anyhow::anyhow!(\"Audit DB connection failed: {e}\"))?;\n        info!(\"Audit service ready\");\n        Some(AuditService::new(audit_pool))\n    } else {\n        info!(\"Audit logging disabled by BUZZ_AUDIT_ENABLED\");\n        None\n    };\n\n    let redis_pool = {\n        let mut cfg = deadpool_redis::Config::from_url(&config.redis_url);\n        cfg.pool = Some(deadpool_redis::PoolConfig::new(config.redis_pool_size));\n        cfg.create_pool(Some(deadpool_redis::Runtime::Tokio1))\n            .map_err(|e| anyhow::anyhow!(\"Redis pool creation failed: {e}\"))?\n    };\n    let redis_health_pool = redis_pool.clone(); // cheap Arc clone — shared with readiness handler\n    let pubsub = Arc::new(\n        PubSubManager::new(&config.redis_url, redis_pool)\n            .await\n            .map_err(|e| anyhow::anyhow!(\"PubSub init failed: {e}\"))?,","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/block/buzz/blob/f956e6fe06a76e50cbd8fba1a162482e752e7f1a/crates/buzz-relay/src/main.rs#L343-L379","documentation":"When BUZZ_AUDIT_ENABLED=true, a small dedicated Postgres pool (max 5 connections, min 1) is opened for the hash-chain audit log. A connection failure here aborts startup with the sqlx error — the relay will not run with a broken audit trail. It uses the same DATABASE_URL as the main pool, so causes overlap with the primary DB connection error.","triggerScenarios":"Same DATABASE_URL connectivity/auth problems as the main pool, or the audit pool's extra connections push the account past its connection limit.","commonSituations":"Audit newly enabled in an environment with a tight connection quota; Postgres briefly unavailable when the relay pod starts; per-user limits on managed Postgres.","solutions":["Verify DATABASE_URL connectivity: `psql \"$DATABASE_URL\" -c 'select 1'`","Raise the Postgres connection limit or lower db_pool_size — the audit pool adds up to 5 more","If auditing is not required in this environment, set BUZZ_AUDIT_ENABLED=false"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# Same URL as the main pool; verify once before boot.\npsql \"$DATABASE_URL\" -c 'select 1' || { echo 'audit DB unreachable'; exit 1; }","typeGuard":null,"tryCatchPattern":"relay:\n  restart: on-failure:5","preventionTips":["Budget 5 extra Postgres connections when BUZZ_AUDIT_ENABLED=true","Start audit-enabled relays only after the DB is ready","Keep audit and primary pools pointed at the same reachable DATABASE_URL"],"tags":["postgres","audit","connection","startup","env-vars"],"backgroundTag":"postgres-connection-failed","analyzedSha":"f956e6fe06a76e50cbd8fba1a162482e752e7f1a","analyzedAt":"2026-08-16T22:11:40.750Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}