{"record":{"id":"18a6ef2bf2c36ea8","repo":"block/buzz","slug":"invalid-buzz-relay-private-key-e","errorCode":null,"errorMessage":"invalid BUZZ_RELAY_PRIVATE_KEY: {e}","messagePattern":"invalid BUZZ_RELAY_PRIVATE_KEY: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/buzz-admin/src/main.rs","lineNumber":412,"sourceCode":"        \"NIP-43 membership list published by buzz-admin\"\n    );\n    Ok(())\n}\n\n/// Connect to DB, Redis pub/sub, and load the relay keypair.\n///\n/// `BUZZ_RELAY_PRIVATE_KEY` is required — the CLI signs kind:13534 events.\nasync fn connect_member_services() -> Result<(Db, Arc<PubSubManager>, Keys)> {\n    let db = connect_db().await?;\n\n    let relay_keypair = {\n        let hex = std::env::var(\"BUZZ_RELAY_PRIVATE_KEY\").map_err(|_| {\n            anyhow::anyhow!(\n                \"BUZZ_RELAY_PRIVATE_KEY is required for add-member/remove-member.\\n\\\n                 The relay must have a stable signing key to publish kind:13534 events.\"\n            )\n        })?;\n        Keys::parse(&hex).map_err(|e| anyhow::anyhow!(\"invalid BUZZ_RELAY_PRIVATE_KEY: {e}\"))?\n    };\n\n    let redis_url =\n        std::env::var(\"REDIS_URL\").unwrap_or_else(|_| \"redis://localhost:6379\".to_string());\n\n    let redis_pool = {\n        let cfg = deadpool_redis::Config::from_url(&redis_url);\n        cfg.create_pool(Some(deadpool_redis::Runtime::Tokio1))\n            .map_err(|e| anyhow::anyhow!(\"Redis pool creation failed: {e}\"))?\n    };\n\n    let pubsub = Arc::new(\n        PubSubManager::new(&redis_url, redis_pool)\n            .await\n            .map_err(|e| anyhow::anyhow!(\"PubSub init failed: {e}\"))?,\n    );\n\n    Ok((db, pubsub, relay_keypair))","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/block/buzz/blob/f956e6fe06a76e50cbd8fba1a162482e752e7f1a/crates/buzz-admin/src/main.rs#L394-L430","documentation":"connect_member_services() found BUZZ_RELAY_PRIVATE_KEY but nostr's Keys::parse() rejected it. Keys::parse accepts a 64-char hex secret key or a bech32 nsec1… string; the error means the value does not decode to a valid secp256k1 secret key (wrong length, non-hex characters, 0x-prefixed hex, or a corrupted/placeholder value). The underlying parse error is appended as {e}.","triggerScenarios":"BUZZ_RELAY_PRIVATE_KEY is set to a public key (npub1…/66 hex chars) instead of the secret, has a 0x prefix, contains a trailing newline/quote from a .env copy, or is a bech32 nsec with a typo. Any add-member/remove-member invocation then fails after DB connect but before signing.","commonSituations":"Copy-pasting the relay's PUBLIC key into the env var; shell quoting mistakes (value captured with quotes `\"abc\"`); values read via `grep | cut` that include whitespace or CRLF from a Windows-edited .env; using a truncated 63-char hex key.","solutions":["Verify the value is exactly 64 hex characters (or a well-formed nsec1… bech32 string) with no whitespace, quotes, or 0x prefix: `echo -n \"$BUZZ_RELAY_PRIVATE_KEY\" | wc -c` should print 64.","Confirm it starts with a hex secret, not npub1… — npub is the PUBLIC key and cannot sign; the relay's own config/secret store has the matching nsec/hex secret.","Re-copy the exact value from the relay's configuration (the same key the relay signs with), then re-run the subcommand.","Sanity-check it parses standalone before retrying: `python3 -c \"import sys; bytes.fromhex(sys.argv[1])\" \"$BUZZ_RELAY_PRIVATE_KEY\"` (or any hex validator)."],"exampleFix":"# before: npub (public key) mistakenly used\nBUZZ_RELAY_PRIVATE_KEY=npub1abcdef...\n\n# after: 64-char hex secret key\nBUZZ_RELAY_PRIVATE_KEY=8i0j...64-hex-chars... (exact secret the relay process uses)","handlingStrategy":"validation","validationCode":"# reject before running the CLI: must be 64 hex chars (or a valid nsec1 string)\nkey=\"${BUZZ_RELAY_PRIVATE_KEY:-}\"\nif ! [[ \"$key\" =~ ^[0-9a-fA-F]{64}$ ]]; then\n  echo \"BUZZ_RELAY_PRIVATE_KEY must be 64 hex chars (got ${#key})\" >&2\n  exit 1\nfi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never store npub values in secret variables — npub is public and cannot sign.","Validate key shape in CI for env files (length + hex charset) to catch truncation/whitespace early.","Prefer bech32 nsec from a secret manager and let Keys::parse handle it, avoiding manual hex edits."],"tags":["buzz-admin","nostr","secp256k1","key-parsing","configuration"],"backgroundTag":"invalid-key-format","analyzedSha":"f956e6fe06a76e50cbd8fba1a162482e752e7f1a","analyzedAt":"2026-08-16T22:11:40.750Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}