block/buzz · error
invalid relay key: {e}
Error message
invalid relay key: {e} What it means
reconcile_channels() found a relay key (from --relay-key or BUZZ_RELAY_PRIVATE_KEY) but nostr's Keys::parse() rejected the value. It must decode to a valid secp256k1 secret key — 64 hex chars or bech32 nsec1… — so wrong length, stray characters, an npub (public key), or quoting artifacts make the parse fail. The parse error is appended as {e}. This is the reconcile-channels twin of the invalid BUZZ_RELAY_PRIVATE_KEY error in add-member/remove-member.
Source
Thrown at crates/buzz-admin/src/main.rs:495
) -> Result<()> {
use buzz_core::kind::KIND_NIP29_GROUP_ADMINS;
use buzz_db::event::EventQuery;
let db = connect_db().await?;
// Resolve relay signing key: arg > env > ephemeral. Force-republish must
// never use an ephemeral key because it replaces an existing authoritative
// snapshot.
let configured_relay_key =
relay_key_arg.or_else(|| std::env::var("BUZZ_RELAY_PRIVATE_KEY").ok());
if channel_arg.is_some() && configured_relay_key.is_none() {
return Err(anyhow::anyhow!(
"--channel requires --relay-key or BUZZ_RELAY_PRIVATE_KEY"
));
}
let relay_keys = match configured_relay_key {
Some(key_hex) => {
Keys::parse(&key_hex).map_err(|e| anyhow::anyhow!("invalid relay key: {e}"))?
}
None => {
let k = Keys::generate();
eprintln!(
"Warning: no relay key provided — using ephemeral key {}",
k.public_key().to_hex()
);
eprintln!("Events signed with this key won't be verifiable after this run.");
eprintln!("Pass --relay-key or set BUZZ_RELAY_PRIVATE_KEY for production use.");
k
}
};
let tenant = resolve_admin_tenant(&db).await?;
let target_channel = channel_arg
.as_deref()
.map(uuid::Uuid::parse_str)
.transpose()View on GitHub (pinned to f956e6fe06)
Solutions
- Check length/charset: 64 hex chars (or full nsec1… string), no whitespace, quotes, or 0x prefix — `echo -n "$KEY" | wc -c` → 64.
- Make sure it is the SECRET key (hex/nsec), not the npub public key.
- Re-copy the exact value from the relay configuration and pass it via a shell variable to avoid quoting damage: `--relay-key "$BUZZ_RELAY_PRIVATE_KEY"`.
- If it still fails, print the parse suffix {e} — it names the exact malformation (bad bech32 checksum, invalid hex, wrong length).
Example fix
# before buzz-admin reconcile-channels --relay-key 0x8a2f... # 0x prefix rejected # after buzz-admin reconcile-channels --relay-key 8a2f... # bare 64-hex secret
Defensive patterns
Strategy: validation
Validate before calling
# validate whatever key source reconcile will use
key="${RELAY_KEY_ARG:-${BUZZ_RELAY_PRIVATE_KEY:-}}"
if ! [[ "$key" =~ ^([0-9a-fA-F]{64}|nsec1[02-9ac-hj-np-z]+)$ ]]; then
echo "relay key must be 64-hex or nsec1 bech32" >&2; exit 1
fi Prevention
- Pass keys via shell variables, never inline literals, to avoid quoting corruption.
- Validate key shape in the same script that builds the command (see validation snippet).
When it happens
Trigger: Passing `--relay-key npub1…` (public key), a key with a 0x prefix, a value shell-quoted with embedded quotes (`--relay-key '"abc"'`), or a truncated copy-paste; or BUZZ_RELAY_PRIVATE_KEY holding the same kinds of malformed values when --relay-key is omitted.
Common situations: Secrets copied from a password manager with whitespace/newlines; .env line wraps splitting the key; operator pastes the relay's PUBLIC key because it is the one shown in relay logs.
Related errors
- invalid BUZZ_RELAY_PRIVATE_KEY: {e}
- BUZZ_RELAY_PRIVATE_KEY is required for add-member/remove-mem
- Redis pool creation failed: {e}
- --channel requires --relay-key or BUZZ_RELAY_PRIVATE_KEY
- invalid --channel UUID: {e}
AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16).
Data as JSON: /api/errors/c0136ceef17c61e3.
Report an issue: GitHub.