block/buzz · critical · anyhow::Error
Configuration error: {e}
Error message
Configuration error: {e} What it means
Fatal startup error wrapping any failure of Config::from_env(), which reads and validates the relay's environment variables. The underlying cause is logged as "Invalid configuration: {e}" just before this error is returned, and the process exits before binding any port. The wrapped message names the exact variable in practically all cases.
Source
Thrown at crates/buzz-relay/src/main.rs:144
)
.with(otel_layer.map(|layer| {
layer.with_filter(telemetry::otel_env_filter(
std::env::var("BUZZ_OTEL_FILTER").ok().as_deref(),
))
}))
.with(trace_context_lookup_layer)
.init();
// Log any exporter-build failure now that the subscriber is installed.
if let telemetry::TracerInit::ExporterBuildFailed(ref e) = tracer_init {
warn!(error = %e, "Failed to build OTLP trace exporter; distributed tracing disabled");
}
info!("Starting buzz-relay");
let config = Config::from_env().map_err(|e| {
error!("Invalid configuration: {e}");
anyhow::anyhow!("Configuration error: {e}")
})?;
info!(
bind_addr = %config.bind_addr,
relay_url = %config.relay_url,
health_port = config.health_port,
metrics_port = config.metrics_port,
max_frame_bytes = config.max_frame_bytes,
audit_enabled = config.audit_enabled,
"Config loaded"
);
let usage_interval_secs = usage_metrics_interval_secs();
let usage_idle_timeout_secs = usage_metrics_idle_timeout_secs(usage_interval_secs);
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,View on GitHub (pinned to f956e6fe06)
Solutions
- Read the "Invalid configuration: {e}" log line — it names the exact variable that failed
- Diff your .env / deployment env against .env.example and add missing variables
- Run a config lint in the deploy pipeline (source the env and assert required vars) before restarting
- Check release notes after upgrading — new required config is the most common regression
Example fix
# before — relay exits: "Configuration error: ..." BUZZ_RELAY_URL=wss://relay.example.com # DATABASE_URL missing # after BUZZ_RELAY_URL=wss://relay.example.com DATABASE_URL=postgres://buzz:secret@db:5432/buzz REDIS_URL=redis://redis:6379
Defensive patterns
Strategy: validation
Validate before calling
# Fail the deploy before the relay boots: every key in .env.example must be set.
missing=0
while read -r key; do
[ -z "${!key+x}" ] && { echo "missing env: $key"; missing=1; }
done < <(grep -oE '^[A-Z_]+' .env.example)
exit $missing Prevention
- Treat .env.example as the authoritative required-var list and diff it in CI
- Source and validate env in the container entrypoint before exec'ing the relay
- Watch release notes for newly required variables when upgrading
When it happens
Trigger: Starting buzz-relay with a missing required variable (e.g. DATABASE_URL, REDIS_URL), a malformed URL, or a non-numeric value where a number is expected (pool sizes, ports, intervals).
Common situations: Forgot `cp .env.example .env` on a fresh clone; a Helm chart or CI secret missing a variable added in a newer release; typo'd variable names; values polluted with quotes or whitespace by secret managers.
Related errors
- RELAY_OWNER_PUBKEY required when BUZZ_REQUIRE_RELAY_MEMBERSH
- BUZZ_RELAY_PRIVATE_KEY is required when BUZZ_REQUIRE_RELAY_M
- Cannot derive a community host from BUZZ_RELAY_URL ({:?}); a
- Redis pool creation failed: {e}
- invalid BUZZ_RELAY_PRIVATE_KEY: {e}
AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16).
Data as JSON: /api/errors/992f6c4f518f558e.
Report an issue: GitHub.