ducaale/xh · error
message-signature: RSA private keys require an explicit…
Error message
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
What it means
When the signing key material is a PEM RSA private key, build_signing_key refuses to guess the algorithm and requires the user to select one explicitly via --unstable-m-sig-alg (rsa-v1_5-sha256 or rsa-pss-sha512), since RSA PEM keys alone don't determine the signature scheme.
Solutions
- Pass --unstable-m-sig-alg=rsa-v1_5-sha256 (classic RSASSA-PKCS1v15)
- Or pass --unstable-m-sig-alg=rsa-pss-sha512 (RSASSA-PSS)
- Or use a non-RSA key (ed25519/ECDSA) if explicit algorithm selection is undesirable
Example fix
# before http --message-signature key=rsa_key.pem ... # after http --message-signature key=rsa_key.pem --unstable-m-sig-alg=rsa-v1_5-sha256 ...
Defensive patterns
Strategy: validation
Validate before calling
// before signing, require an explicit algorithm for RSA PEM keys
if pem_contains_rsa_private_key(key_material) && m_sig_alg.is_none() {
anyhow::bail!("RSA keys require --unstable-m-sig-alg=rsa-v1_5-sha256 or rsa-pss-sha512");
} Type guard
fn needs_explicit_alg(pem: &str, alg: Option<&AlgorithmName>) -> bool {
alg.is_none() && pem.contains("BEGIN") && parse_pem_secret_key(pem, &[AlgorithmName::RsaV1_5Sha256, AlgorithmName::RsaPssSha512]).is_some()
} Try / catch
match sign_request(&req, &components, &key) {
Ok(s) => s,
Err(e) if e.to_string().contains("RSA private keys require an explicit algorithm") => {
eprintln!("re-run with --unstable-m-sig-alg=rsa-v1_5-sha256 or rsa-pss-sha512");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Always pass --unstable-m-sig-alg when using RSA keys
- Document required flags per key type in scripts/wrappers
- Validate key type vs. chosen algorithm before invoking
- Prefer ed25519/ECDSA keys where algorithm inference is safe
When it happens
Trigger: sign_request called with an RSA PEM private key and no explicit algorithm (m_sig_alg unset or set to a non-RSA algorithm).
Common situations: Users supplying a standard RSA .pem signing key without the --unstable-m-sig-alg flag; defaults tuned for ed25519/ECDSA keys.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- message-signature: Duplicate covered component identifier
- message-signature: Failed to parse PEM private key…
- Unsupported option
- Unknown option
- is not a valid value
AI-assisted analysis of ducaale/xh@2404aceecc (2026-09-13).
Data as JSON: /api/errors/03df4331000b349e.
Report an issue: GitHub.
Appendix: source
Thrown at src/message_signature.rs:271
if pem.contains("-----BEGIN") {
if let Some(secret) = parse_pem_secret_key(
pem,
&[
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)View on GitHub (pinned to 2404aceecc)