block/buzz · error · anyhow::Error
PubSub init failed
Error message
PubSub init failed: {e} What it means
Unlike pool creation, PubSubManager::new actually dials Redis to set up pub/sub plumbing. It fails on live connection problems: server unreachable (connection refused / DNS failure / firewall), auth failure (requirepass with no password or wrong one), or a Redis version/protocol mismatch. The wrapped {e} carries the underlying redis error.
Solutions
- Health-check with the same URL: redis-cli -u "$REDIS_URL" ping (expect PONG).
- Start Redis (docker compose up -d redis) or fix the host/port in REDIS_URL.
- Embed credentials if needed: redis://:password@host:6379, and rediss:// for TLS.
- If the job races container startup, add a readiness wait on the Redis port before invoking buzz-admin.
Example fix
# before REDIS_URL=redis://redis:6379 # container still starting -> PubSub init failed # after until redis-cli -u "$REDIS_URL" ping 2>/dev/null | grep -q PONG; do sleep 1; done buzz-admin add-member --pubkey <hex> --role member
Defensive patterns
Strategy: retry
Validate before calling
# preflight: prove Redis is reachable with the exact URL before the CLI runs
redis-cli -u "$REDIS_URL" ping | grep -q PONG || { echo 'Redis not ready' >&2; exit 3; } Try / catch
// wrap admin invocations with bounded retry only for connection-class failures
for attempt in 0..3 {
match run(cmd).await {
Ok(v) => return Ok(v),
Err(e) if e.to_string().contains("PubSub init failed") && attempt < 2 => {
backoff(attempt).await; // Redis may still be starting; retry with delay
}
Err(e) => return Err(e), // auth/config failures will not heal — surface immediately
}
} Prevention
- Gate admin jobs on a Redis readiness probe (redis-cli PING) instead of a fixed sleep.
- Keep the relay's and the CLI's REDIS_URL identical — one secret, two consumers.
- Include the password in the URL when Redis requires auth; test with the same URL the CLI uses.
When it happens
Trigger: REDIS_URL points at a Redis that is down or firewalled; Redis requires a password and the URL lacks :password@; TLS mismatch (redis:// against a TLS-only port); k8s service not ready when the admin job starts.
Common situations: Running buzz-admin add-member without starting the docker-compose redis; rotating Redis credentials without updating REDIS_URL; job races a starting container.
Related errors
- PubSub init failed
- Redis pool creation failed
- Audit DB connection failed
- BUZZ_RELAY_PRIVATE_KEY is required for…
- --channel requires --relay-key or BUZZ_RELAY_PRIVATE_KEY
AI-assisted analysis of block/buzz@ef2aa1ae38 (2026-08-20).
Data as JSON: /api/errors/c6d0c368d370c07a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/buzz-admin/src/main.rs:572
The relay must have a stable signing key to publish kind:13534 events."
)
})?;
Keys::parse(&hex).map_err(|e| anyhow::anyhow!("invalid BUZZ_RELAY_PRIVATE_KEY: {e}"))?
};
let redis_url =
std::env::var("REDIS_URL").unwrap_or_else(|_| "redis://localhost:6379".to_string());
let redis_pool = {
let cfg = deadpool_redis::Config::from_url(&redis_url);
cfg.create_pool(Some(deadpool_redis::Runtime::Tokio1))
.map_err(|e| anyhow::anyhow!("Redis pool creation failed: {e}"))?
};
let pubsub = Arc::new(
PubSubManager::new(&redis_url, redis_pool)
.await
.map_err(|e| anyhow::anyhow!("PubSub init failed: {e}"))?,
);
Ok((db, pubsub, relay_keypair))
}
async fn connect_db() -> Result<Db> {
let db_url = std::env::var("DATABASE_URL")
.unwrap_or_else(|_| "postgres://buzz:buzz_dev@localhost:5432/buzz".to_string());
let db = Db::new(
&DbConfig {
database_url: db_url,
..DbConfig::default()
}
.with_session_timeouts_from_env(),
)
.await?;
Ok(db)
}View on GitHub (pinned to ef2aa1ae38)