block/buzz · critical · anyhow::Error
BUZZ_RELAY_PRIVATE_KEY is required when BUZZ_REQUIRE_RELAY_M
Error message
BUZZ_RELAY_PRIVATE_KEY is required when BUZZ_REQUIRE_RELAY_MEMBERSHIP=true. NIP-43 events signed with an ephemeral key become unverifiable after restart.
What it means
NIP-43 membership events are signed by the relay's own keypair, so enforcement requires the stable BUZZ_RELAY_PRIVATE_KEY. This fatal error fires when BUZZ_REQUIRE_RELAY_MEMBERSHIP=true but no private key is configured — events signed with an ephemeral key would become unverifiable after restart, so boot aborts before any DB mutations.
Source
Thrown at crates/buzz-relay/src/main.rs:248
// NIP-43: if membership enforcement is on, a valid owner pubkey is required.
// config.rs already strips invalid values with a warning; catch the resulting
// None here so we fail fast with a clear message rather than starting a relay
// that no one can administer.
if config.require_relay_membership && config.relay_owner_pubkey.is_none() {
error!(
"BUZZ_REQUIRE_RELAY_MEMBERSHIP=true but RELAY_OWNER_PUBKEY is not set or invalid. \
Set RELAY_OWNER_PUBKEY to a valid 64-char hex pubkey."
);
return Err(anyhow::anyhow!(
"RELAY_OWNER_PUBKEY required when BUZZ_REQUIRE_RELAY_MEMBERSHIP=true"
));
}
// NIP-43: relay membership requires a stable signing key.
// Check this before any DB mutations so we fail fast — no point backfilling
// or bootstrapping if we'll reject the config anyway.
if config.require_relay_membership && config.relay_private_key.is_none() {
return Err(anyhow::anyhow!(
"BUZZ_RELAY_PRIVATE_KEY is required when BUZZ_REQUIRE_RELAY_MEMBERSHIP=true. \
NIP-43 events signed with an ephemeral key become unverifiable after restart."
));
}
// NIP-43 / multi-tenant: seed the deployment's *own* community before any
// membership backfill or owner bootstrap, so those writes are scoped to a
// real `(community_id, pubkey)` and not a global pubkey. The host is derived
// from `relay_url` with the *same* normalization request resolution uses
// (`relay_url_authority` → `normalize_host`), so the bootstrapped owner lands
// in exactly the community that live requests for this host will resolve to.
//
// `ensure_configured_community` is idempotent, so this is safe to run every
// startup. An empty authority (unparseable `relay_url`)
// is a misconfiguration — fail fast when membership is enforced rather than
// seeding an empty-host community that no request can ever resolve to.
let deployment_community = {
let host = buzz_relay::tenant::relay_url_authority(&config.relay_url);View on GitHub (pinned to f956e6fe06)
Solutions
- Generate a stable secp256k1 private key and set BUZZ_RELAY_PRIVATE_KEY (64-char hex)
- Confirm the secret actually reaches the process: `env | grep BUZZ_RELAY_PRIVATE_KEY`
- Or set BUZZ_REQUIRE_RELAY_MEMBERSHIP=false until the key is provisioned
Example fix
# before BUZZ_REQUIRE_RELAY_MEMBERSHIP=true # BUZZ_RELAY_PRIVATE_KEY unset # after BUZZ_REQUIRE_RELAY_MEMBERSHIP=true BUZZ_RELAY_PRIVATE_KEY=81100d7eeb199f8565d5a9c0d5f01b5f5a3395e8b4e4b6b1e2a9c8d7e6f5a4b3
Defensive patterns
Strategy: validation
Validate before calling
# Both must be present together before boot.
if [ "$BUZZ_REQUIRE_RELAY_MEMBERSHIP" = "true" ] && [ -z "${BUZZ_RELAY_PRIVATE_KEY:-}" ]; then
echo 'BUZZ_RELAY_PRIVATE_KEY is required when BUZZ_REQUIRE_RELAY_MEMBERSHIP=true'
exit 1
fi Prevention
- Provision the relay signing key in the secret store before enabling enforcement
- Smoke-test the pod env (`env | grep BUZZ_RELAY_PRIVATE_KEY`) in staging
- Generate the key once and back it up — NIP-43 events become unverifiable if it changes
When it happens
Trigger: BUZZ_REQUIRE_RELAY_MEMBERSHIP=true with BUZZ_RELAY_PRIVATE_KEY unset (checked before backfill/bootstrap so nothing is written first).
Common situations: Enabling enforcement on a deployment that previously relied on dev-mode key generation; the k8s secret not mounted into the pod; key present locally but missing in the CI/staging environment.
Related errors
- RELAY_OWNER_PUBKEY required when BUZZ_REQUIRE_RELAY_MEMBERSH
- invalid BUZZ_RELAY_PRIVATE_KEY: {e}
- Configuration error: {e}
- Cannot derive a community host from BUZZ_RELAY_URL ({:?}); a
- Redis pool creation failed: {e}
AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16).
Data as JSON: /api/errors/49bad9a66c1211bf.
Report an issue: GitHub.