block/buzz · critical · anyhow::Error
failed to initialize media storage
Error message
failed to initialize media storage: {e} What it means
Fatal startup error: buzz_media::MediaStorage::new() failed while standing up media storage from config.media (after validate() already passed). This step constructs the S3/MinIO client against the configured endpoint, bucket, credentials, region, and addressing style — failures here are connectivity, credentials, bucket, or endpoint-shape problems.
Solutions
- Verify the endpoint and bucket from the same host: aws --endpoint-url $BUZZ_MEDIA_S3_ENDPOINT s3 ls s3://$BUZZ_MEDIA_S3_BUCKET (or mc for MinIO)
- Create the bucket if missing, or fix its name
- Update credentials/region: region must match the endpoint's region for real AWS S3
- Check the addressing style matches your S3 implementation (path-style for MinIO)
- Restart the relay once storage checks pass
Example fix
# before export BUZZ_MEDIA_S3_ENDPOINT=http://minio:9000 export BUZZ_MEDIA_S3_BUCKET=media # bucket never created -> init fails # after mc alias set local http://minio:9000 $MINIO_ROOT_USER $MINIO_ROOT_PASSWORD mc mb local/media export BUZZ_MEDIA_S3_ENDPOINT=http://minio:9000 export BUZZ_MEDIA_S3_BUCKET=media
Defensive patterns
Strategy: validation
Validate before calling
# Boot gate: prove bucket access with the same coordinates the relay uses:
aws --endpoint-url "$BUZZ_MEDIA_S3_ENDPOINT" s3 ls "s3://${BUZZ_MEDIA_S3_BUCKET:?}" >/dev/null \
|| { echo 'media bucket unreachable'; exit 1; } Try / catch
// Retry startup only for transient S3 outages; credential/bucket errors are // configuration fixes followed by a restart.
Prevention
- Create the media bucket before first relay boot
- Keep endpoint, region, credentials, and addressing style consistent (path-style for MinIO)
- Rotate S3 keys through the same deploy that restarts the relay
When it happens
Trigger: S3 endpoint unreachable or wrong (self-hosted MinIO down / wrong port), the bucket does not exist, credentials are rejected, path-style vs virtual-host addressing mismatch, or an AWS region that does not match the endpoint so signatures are scoped wrong.
Common situations: MinIO container not up when the relay boots; bucket name typo; rotating S3 keys without updating the relay secret; switching between path-style (MinIO default) and virtual-host style without DNS to match.
Related errors
- git conformance probe failed
- invalid media config
- Audit DB connection failed
- DB connection failed
- PubSub init failed
AI-assisted analysis of block/buzz@ef2aa1ae38 (2026-08-20).
Data as JSON: /api/errors/5e2ec4a3b7550791.
Report an issue: GitHub.
Appendix: source
Thrown at crates/buzz-relay/src/main.rs:514
.connect(search_db_url)
.await
.map_err(|e| anyhow::anyhow!("Search DB connection failed: {e}"))?;
let search_metrics_pool = search_pool.clone();
let search = SearchService::new(search_pool);
info!(
replica = config.read_database_url.is_some(),
"Search service ready (Postgres FTS)"
);
let workflow_config = buzz_workflow::WorkflowConfig::default();
let workflow_engine = Arc::new(WorkflowEngine::new(db.clone(), workflow_config));
config
.media
.validate()
.map_err(|e| anyhow::anyhow!("invalid media config: {e}"))?;
let media_storage = buzz_media::MediaStorage::new(&config.media)
.map_err(|e| anyhow::anyhow!("failed to initialize media storage: {e}"))?;
info!("Media storage connected");
let (app_state, audit_shutdown) = AppState::new(
config.clone(),
db,
redis_health_pool,
audit,
pubsub,
auth,
search,
Arc::clone(&workflow_engine),
relay_keypair,
media_storage,
);
let state = Arc::new(app_state);
// Inter-relay mesh (BUZZ_MESH seam). `boot_mesh` returns None when the
// kill switch is off — nothing is bound, published, or spawned, so theView on GitHub (pinned to ef2aa1ae38)