awslabs/llrt · critical

HMAC-MD5 not supported

Error message

HMAC-MD5 not supported

What it means

This panic in the RustCrypto provider's `hmac` method fires when HashAlgorithm::Md5 is requested. The Rust provider supports HMAC over SHA-1, SHA-256, SHA-384, and SHA-512 but deliberately omits MD5, panicking with 'HMAC-MD5 not supported'. Unlike the Ring provider's message, this one is generic about the reason.

Solutions

  1. Use HMAC-SHA256 (or SHA-1 for legacy) instead of HMAC-MD5.
  2. Add an MD5-capable HMAC implementation (e.g. enable the Md5 crate) or a pure-JS fallback.
  3. Validate the algorithm before constructing the HMAC and return a proper error instead of panicking.
  4. Check which provider your build uses and its supported algorithm matrix.

Example fix

// before
createHmac('md5', key); // panics
// after
createHmac('sha1', key); // supported (legacy) — or preferably 'sha256'
Defensive patterns

Strategy: validation

Validate before calling

if (algorithm === 'md5') throw new Error('HMAC-MD5 not supported by the Rust provider; use sha1/sha256/sha384/sha512');

Type guard

function rustProviderSupportsHmac(alg) {
  return ['sha1', 'sha256', 'sha384', 'sha512'].includes(alg);
}

Try / catch

match rust_hmac(alg, key) {
    Err(HmacError::UnsupportedMd5) => use_pure_js_md5_hmac(key),
    Ok(h) => h,
}

Prevention

When it happens

Trigger: Requesting an HMAC with HashAlgorithm::Md5 while the RustCrypto (rust) provider is the active backend.

Common situations: Legacy MD5-based signature schemes (old APIs, S3-style auth quirks) being ported to this runtime; the md5 algorithm string accepted elsewhere in the crypto module but rejected for HMAC.

Related errors


AI-assisted analysis of awslabs/llrt@742fc00b82 (2026-09-12). Data as JSON: /api/errors/fd006b624866a839. Report an issue: GitHub.

Appendix: source

Thrown at modules/llrt_crypto/src/provider/rust/mod.rs:161

pub struct RustCryptoProvider;

impl CryptoProvider for RustCryptoProvider {
    type Digest = RustDigest;
    type Hmac = RustHmac;

    fn digest(&self, algorithm: HashAlgorithm) -> Self::Digest {
        match algorithm {
            HashAlgorithm::Md5 => RustDigest::Md5(md5::Md5::new()),
            HashAlgorithm::Sha1 => RustDigest::Sha1(Sha1::new()),
            HashAlgorithm::Sha256 => RustDigest::Sha256(Sha256::new()),
            HashAlgorithm::Sha384 => RustDigest::Sha384(Sha384::new()),
            HashAlgorithm::Sha512 => RustDigest::Sha512(Sha512::new()),
        }
    }

    fn hmac(&self, algorithm: HashAlgorithm, key: &[u8]) -> Self::Hmac {
        match algorithm {
            HashAlgorithm::Md5 => panic!("HMAC-MD5 not supported"),
            HashAlgorithm::Sha1 => RustHmac::Sha1(HmacImpl::<Sha1>::new_from_slice(key).unwrap()),
            HashAlgorithm::Sha256 => {
                RustHmac::Sha256(HmacImpl::<Sha256>::new_from_slice(key).unwrap())
            },
            HashAlgorithm::Sha384 => {
                RustHmac::Sha384(HmacImpl::<Sha384>::new_from_slice(key).unwrap())
            },
            HashAlgorithm::Sha512 => {
                RustHmac::Sha512(HmacImpl::<Sha512>::new_from_slice(key).unwrap())
            },
        }
    }

    fn ecdsa_sign(
        &self,
        curve: EllipticCurve,
        private_key_der: &[u8],
        digest: &[u8],

View on GitHub (pinned to 742fc00b82)