zeroclaw-labs/zeroclaw · error

system RNG failed

Error message

system RNG failed

What it means

ReceiptKeyGenerator::new() creates a random 256-bit HMAC key using ring's SystemRandom. fill() virtually never fails; when it does, the operating system's entropy source is unavailable (no /dev/urandom, getrandom(2) blocked by a sandbox policy). The library treats working system entropy as a hard requirement and panics.

Source

Thrown at crates/zeroclaw-runtime/src/agent/tool_receipts.rs:32

#[derive(Clone)]
pub struct ReceiptGenerator {
    key: Vec<u8>,
}

impl Default for ReceiptGenerator {
    fn default() -> Self {
        Self::new()
    }
}

impl ReceiptGenerator {
    /// Create a new generator with a random 256-bit ephemeral key.
    pub fn new() -> Self {
        use ring::rand::{SecureRandom, SystemRandom};
        let mut key = vec![0u8; 32];
        SystemRandom::new()
            .fill(&mut key)
            .expect("system RNG failed");
        Self { key }
    }

    #[cfg(test)]
    pub fn with_key(key: Vec<u8>) -> Self {
        Self { key }
    }

    /// Generate a receipt for a tool execution.
    /// The receipt encodes: tool_name | args_hash | result_hash | timestamp
    /// into an HMAC-SHA256 digest, formatted as `zc-receipt-{timestamp}-{hash}`.
    pub fn generate(
        &self,
        tool_name: &str,
        args: &serde_json::Value,
        result: &str,
        timestamp: u64,
    ) -> String {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Ensure /dev/urandom exists and is readable inside the container or chroot (install/mount it, or use a fuller base image).
  2. Adjust the container security profile (seccomp, AppArmor, gVisor config) to allow getrandom(2) / reads of /dev/urandom.
  3. For deterministic tests, use ReceiptKeyGenerator::with_key(...) instead of new() so no system RNG is needed.
Defensive patterns

Strategy: validation

Validate before calling

// Probe the OS entropy source before starting in locked-down environments:
let mut probe = [0u8; 1];
getrandom::getrandom(&mut probe)
    .map_err(|e| anyhow::anyhow!("system RNG unavailable: {e}; check /dev/urandom and seccomp policy"))?;
let generator = ReceiptKeyGenerator::new();

Prevention

When it happens

Trigger: Calling ReceiptKeyGenerator::new() in an environment where the OS randomness source is inaccessible: containers with a seccomp/AppArmor profile denying getrandom, a chroot without /dev/urandom mounted, or exotic platforms early in boot before the kernel entropy pool is ready.

Common situations: Minimal distroless/alpine containers with restrictive runtime profiles; gVisor/Firecracker sandboxes with narrowed syscall surfaces; test harnesses running inside locked-down CI executors.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/0dd5c7b94b4e0c4e. Report an issue: GitHub.