block/buzz · critical · anyhow::Error

Failed to backfill pubkey_allowlist (required when…

Error message

Failed to backfill pubkey_allowlist (required when BUZZ_REQUIRE_RELAY_MEMBERSHIP=true): {e}

What it means

Fatal startup error: db.backfill_from_allowlist(community) — the idempotent migration of existing pubkey_allowlist entries into relay_members — failed while BUZZ_REQUIRE_RELAY_MEMBERSHIP=true. It runs before owner bootstrap precisely so existing allowlisted users keep access when enforcement turns on; failing here means startup must not continue.

Solutions

  1. Inspect {e}: Ok variants matter — this error path is only Err, so identify the SQL failure
  2. Ensure migrations are applied so both pubkey_allowlist and relay_members exist with expected columns
  3. Grant the relay DB user the needed read/write on those tables, then restart
  4. If transient, restart once Postgres is healthy — the backfill is idempotent and safe to re-run
Defensive patterns

Strategy: retry

Validate before calling

# Confirm both tables exist before enabling enforcement:
psql "$DATABASE_URL" -c '\dt' | grep -E 'pubkey_allowlist|relay_members'

Try / catch

// Retry startup with backoff for transient DB errors; stop and fix grants/
// migrations when {e} indicates permission denied or undefined relation.

Prevention

When it happens

Trigger: DB error during the backfill write: connectivity blip, insufficient privileges on the allowlist/relay_members tables, or schema drift where the pubkey_allowlist table does not exist (migrations not applied) on a deployment that has allowlist data elsewhere.

Common situations: Enabling membership enforcement on a long-running relay that used an allowlist; least-privilege DB role missing rights on the newly-written table; DB failover mid-boot.

Related errors


AI-assisted analysis of block/buzz@ef2aa1ae38 (2026-08-20). Data as JSON: /api/errors/8f7bd4781467cee0. Report an issue: GitHub.

Appendix: source

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

                }
            }
        }
    };

    // NIP-43: migrate any existing pubkey_allowlist entries to relay_members.
    // Idempotent — safe to run every startup. Must run before bootstrap_owner
    // so that existing allowlist users become relay members before the owner
    // is promoted (otherwise enabling membership locks everyone out).
    if let Some(community) = deployment_community {
        match db.backfill_from_allowlist(community).await {
            Ok(0) => {}
            Ok(n) => info!("Backfilled {n} pubkey_allowlist entries into relay_members"),
            Err(e) => {
                if config.require_relay_membership {
                    error!(
                        "Fatal: failed to backfill allowlist with membership enforcement enabled: {e}"
                    );
                    return Err(anyhow::anyhow!(
                        "Failed to backfill pubkey_allowlist (required when BUZZ_REQUIRE_RELAY_MEMBERSHIP=true): {e}"
                    ));
                } else {
                    error!("Failed to backfill pubkey_allowlist (non-fatal): {e}");
                }
            }
        }
    }

    // NIP-43: ensure the configured relay owner always holds the owner role
    // within the deployment community.
    if let (Some(community), Some(owner_pubkey)) =
        (deployment_community, config.relay_owner_pubkey.as_ref())
    {
        match db.bootstrap_owner(community, owner_pubkey).await {
            Ok(()) => info!(pubkey = %owner_pubkey, "Relay owner bootstrapped"),
            Err(e) => {
                if config.require_relay_membership {

View on GitHub (pinned to ef2aa1ae38)