{"record":{"id":"b6de6fc580d63286","repo":"ducaale/xh","slug":"message-signature-failed-to-create-hmac-key","errorCode":null,"errorMessage":"message-signature: Failed to create HMAC key: {:?}","messagePattern":"message-signature: Failed to create HMAC key: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/message_signature.rs","lineNumber":290,"sourceCode":"                    \"message-signature: RSA private keys require an explicit algorithm. Use --unstable-m-sig-alg=rsa-v1_5-sha256 or --unstable-m-sig-alg=rsa-pss-sha512\"\n                );\n            }\n            bail!(\n                \"message-signature: Failed to parse PEM private key. Supported algorithms: ed25519, ecdsa-p256-sha256, ecdsa-p384-sha384, rsa-v1_5-sha256, rsa-pss-sha512\"\n            );\n        }\n    }\n\n    build_hmac_signing_key(key_material, key_id)\n}\n\nfn build_hmac_signing_key(\n    key_material: &[u8],\n    key_id: &str,\n) -> Result<(MessageSigningKey, AlgorithmName)> {\n    let encoded = STANDARD.encode(key_material);\n    let shared_key = SharedKey::from_base64(&AlgorithmName::HmacSha256, &encoded)\n        .map_err(|e| anyhow!(\"message-signature: Failed to create HMAC key: {:?}\", e))?;\n    Ok((\n        MessageSigningKey::Shared(shared_key, key_id.to_string()),\n        AlgorithmName::HmacSha256,\n    ))\n}\n\nfn build_signing_key_with_algorithm(\n    key_material: &[u8],\n    key_id: &str,\n    algorithm: &AlgorithmName,\n) -> Result<(MessageSigningKey, AlgorithmName)> {\n    if algorithm == &AlgorithmName::HmacSha256 {\n        return build_hmac_signing_key(key_material, key_id);\n    }\n\n    let secret = if let Ok(pem) = std::str::from_utf8(key_material) {\n        if pem.contains(\"-----BEGIN\") {\n            SecretKey::from_pem(algorithm, pem).with_context(|| {","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/ducaale/xh/blob/2404aceecc08b0b2d100fedc96f57745cd5904dc/src/message_signature.rs#L272-L308","documentation":"While building an HMAC-SHA256 shared signing key, the base64-encoded key material is passed to `SharedKey::from_base64`, which validates the encoding. If that call fails (e.g. the material is not valid base64 after re-encoding, or fails key constraints), the error is wrapped with this message via `anyhow!` and propagated up through `build_signing_key`.","triggerScenarios":"Passing `--unstable-m-sig-key` material that `SharedKey::from_base64` rejects for the HmacSha256 algorithm — e.g. malformed base64 content or an invalid key length for the algorithm.","commonSituations":"Pasting a key with whitespace/newlines; supplying a PEM or hex key where raw/base64 material is expected; truncating a key when copying it from a secret manager.","solutions":["Verify the key material is valid base64 of the correct length for HMAC-SHA256; re-encode with `base64 -w0 < keyfile`.","Check for stray whitespace, quotes, or newlines in the value passed via `--unstable-m-sig-key` or the env var.","Confirm the key is raw key bytes (not PEM/hex); convert appropriately before passing it."],"exampleFix":"// before\nxh --unstable-m-sig-id=k1 --unstable-m-sig-key=\"$(cat key.pem)\" POST https://api.example.com\n// after\nxh --unstable-m-sig-id=k1 --unstable-m-sig-key=\"$(base64 -w0 key.bin)\" POST https://api.example.com","handlingStrategy":"validation","validationCode":"# validate base64 key material before use:\necho \"$KEY\" | base64 -d >/dev/null 2>&1 || { echo 'key is not valid base64'; exit 1; }","typeGuard":null,"tryCatchPattern":"// Rust caller:\nmatch build_signing_key_with_algorithm(...) {\n    Err(e) if e.to_string().contains(\"Failed to create HMAC key\") => {\n        eprintln!(\"check key encoding: must be valid base64 raw key bytes\");\n    }\n    other => other?,\n}","preventionTips":["Re-encode keys with `base64 -w0` before passing them.","Strip whitespace/newlines from secret-manager output.","Know the expected key format (raw bytes, base64) — never PEM or hex unless documented."],"tags":["hmac","base64","cryptography","key-format"],"backgroundTag":"invalid-argument-format","analyzedSha":"2404aceecc08b0b2d100fedc96f57745cd5904dc","analyzedAt":"2026-09-13T19:13:33.814Z","contentChangedAt":"2026-09-13T19:13:33.814Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}