nautechsystems/nautilus_trader · error

Failed to generate RSA signature

Error message

Failed to generate RSA signature

What it means

After successfully loading the RSA key pair, `rsa_signature` signs the data with RSA PKCS#1 v1.5 + SHA-256 using ring's `KeyPair::sign`. This error is returned if ring's signing operation fails. With a validly constructed `KeyPair` this is rare, since PKCS#1 signing over any byte slice has no runtime failure modes other than RNG failure.

Source

Thrown at crates/cryptography/src/signing.rs:73

        anyhow::bail!("PEM does not contain a private key");
    }

    // Construct RSA key pair from PKCS#8 DER bytes
    let key_pair = KeyPair::from_pkcs8(pem.contents())
        .map_err(|_| anyhow::anyhow!("Failed to decode RSA private key"))?;

    // Prepare RNG and output buffer (signature length = modulus length)
    let rng = lc_rand::SystemRandom::new();
    let mut signature = vec![0u8; key_pair.public_modulus_len()];

    key_pair
        .sign(
            &lc_signature::RSA_PKCS1_SHA256,
            &rng,
            data.as_bytes(),
            &mut signature,
        )
        .map_err(|_| anyhow::anyhow!("Failed to generate RSA signature"))?;

    Ok(BASE64_STANDARD.encode(signature))
}

/// Signs `data` using Ed25519 with the provided private key seed.
///
/// # Errors
///
/// Returns an error if the provided private key seed is invalid or signature creation fails.
pub fn ed25519_signature(private_key: &[u8], data: &str) -> anyhow::Result<String> {
    let signing_key = SigningKey::from_bytes(
        private_key
            .try_into()
            .map_err(|_| anyhow::anyhow!("Invalid Ed25519 private key length"))?,
    );
    let signature: Ed25519Signature = signing_key.sign(data.as_bytes());
    Ok(BASE64_STANDARD.encode(signature.to_bytes()))
}

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check that the OS entropy source is available (`/dev/urandom` readable, `getrandom` syscall permitted); fix container seccomp/sandbox policy if it blocks it.
  2. Retry the operation once — RNG failures are typically transient/environmental.
  3. If it persists, verify ring/lc-rand builds correctly for the target platform and update the dependency versions.
  4. Confirm the key loaded successfully (no preceding 3920 error) — a corrupted key path should be ruled out first by testing key validity with `openssl pkey -check`.
Defensive patterns

Strategy: retry

Try / catch

// sign failures here are environmental (RNG); retry a bounded number of times
for attempt in 0..3 {
    match rsa_signature(&pem, data) {
        Ok(sig) => break Ok(sig),
        Err(e) if e.to_string().contains("Failed to generate RSA signature") && attempt < 2 => {
            eprintln!("sign attempt {} failed, retrying: {e}", attempt + 1);
            continue;
        }
        Err(e) => break Err(e),
    }
}

Prevention

When it happens

Trigger: Calling `rsa_signature(pem, data)` (via `py_rsa_signature` or tests) where the underlying `lc_rand::SystemRandom` cannot supply randomness (entropy source unavailable) or ring rejects the sign request internally — the sign call returns `Err` and is mapped to this message.

Common situations: Running on a platform/container where the system entropy source is unavailable or restricted (hardened sandbox, exotic OS build of ring without RNG support); extremely large `data` inputs are NOT a cause — RSA PKCS#1 hashes first.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/ac22544d52f45198. Report an issue: GitHub.