ducaale/xh · error
message-signature: Failed to parse PEM private key…
Error message
message-signature: Failed to parse PEM private key. Supported algorithms: ed25519, ecdsa-p256-sha256, ecdsa-p384-sha384, rsa-v1_5-sha256, rsa-pss-sha512
What it means
build_signing_key failed to parse the supplied PEM private key with any supported algorithm's parser. After ruling out RSA keys needing explicit algorithm selection, it bails listing the supported algorithms: ed25519, ecdsa-p256-sha256, ecdsa-p384-sha384, rsa-v1_5-sha256, rsa-pss-sha512.
Solutions
- Verify the file is an unencrypted PEM private key (check BEGIN PRIVATE KEY header)
- Use a supported key type: ed25519, ECDSA P-256/P-384, or RSA (with explicit --unstable-m-sig-alg)
- Re-export the key without a passphrase and in PKCS#8 PEM format
- If intending HMAC, pass the raw secret without PEM markers
Example fix
# before (public key passed) http --message-signature key=pubkey.pem ... # after (private key, supported format) http --message-signature key=ed25519_private.pem ...
Defensive patterns
Strategy: validation
Validate before calling
// pre-check the PEM before signing
fn pem_looks_valid(key: &str) -> bool {
key.contains("-----BEGIN") && key.contains("PRIVATE KEY-----") && !key.contains("ENCRYPTED")
}
assert!(pem_looks_valid(&std::fs::read_to_string("key.pem")?)); Type guard
fn is_supported_private_pem(pem: &str) -> bool {
pem.contains("PRIVATE KEY-----") && !pem.contains("ENCRYPTED") && !pem.contains("PUBLIC KEY")
} Try / catch
match sign_request(&req, &components, &key) {
Ok(s) => s,
Err(e) if e.to_string().contains("Failed to parse PEM private key") => {
eprintln!("check key format; supported: ed25519, ecdsa-p256-sha256, ecdsa-p384-sha384, rsa-v1_5-sha256, rsa-pss-sha512");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Verify the PEM header says PRIVATE KEY, not PUBLIC KEY or CERTIFICATE
- Decrypt passphrase-protected keys before use
- Use PKCS#8 PEM output when exporting keys (openssl pkey -traditional-free / -outform PEM)
- Test key loading in CI with a known-good key
When it happens
Trigger: sign_request called with key material that is neither a parseable ed25519/ECDSA/RSA PEM nor valid HMAC secret, e.g. malformed PEM, encrypted PEM, a public key instead of a private key, or an unsupported key type.
Common situations: Wrong file passed as key (certificate or public key); PEM encrypted with a passphrase; truncated/corrupted PEM; unsupported curve or key format (PKCS#8 variants not handled).
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- message-signature: Duplicate covered component identifier
- message-signature: RSA private keys require an explicit…
- message-signature: Failed to create HMAC key
AI-assisted analysis of ducaale/xh@2404aceecc (2026-09-13).
Data as JSON: /api/errors/1c5e797b614726c8.
Report an issue: GitHub.
Appendix: source
Thrown at src/message_signature.rs:275
AlgorithmName::Ed25519,
AlgorithmName::EcdsaP256Sha256,
AlgorithmName::EcdsaP384Sha384,
],
) {
let alg = secret.alg();
return Ok((MessageSigningKey::Secret(secret, key_id.to_string()), alg));
}
if parse_pem_secret_key(
pem,
&[AlgorithmName::RsaV1_5Sha256, AlgorithmName::RsaPssSha512],
)
.is_some()
{
bail!(
"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"
);
}
bail!(
"message-signature: Failed to parse PEM private key. Supported algorithms: ed25519, ecdsa-p256-sha256, ecdsa-p384-sha384, rsa-v1_5-sha256, rsa-pss-sha512"
);
}
}
build_hmac_signing_key(key_material, key_id)
}
fn build_hmac_signing_key(
key_material: &[u8],
key_id: &str,
) -> Result<(MessageSigningKey, AlgorithmName)> {
let encoded = STANDARD.encode(key_material);
let shared_key = SharedKey::from_base64(&AlgorithmName::HmacSha256, &encoded)
.map_err(|e| anyhow!("message-signature: Failed to create HMAC key: {:?}", e))?;
Ok((
MessageSigningKey::Shared(shared_key, key_id.to_string()),
AlgorithmName::HmacSha256,View on GitHub (pinned to 2404aceecc)