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
- Ensure /dev/urandom exists and is readable inside the container or chroot (install/mount it, or use a fuller base image).
- Adjust the container security profile (seccomp, AppArmor, gVisor config) to allow getrandom(2) / reads of /dev/urandom.
- 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
- Verify /dev/urandom is mounted and readable in minimal containers or chroots.
- Allow getrandom(2) in seccomp/AppArmor/gVisor profiles for the agent process.
- Use ReceiptKeyGenerator::with_key() in deterministic tests to sidestep the system RNG.
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
- Docker runtime environment passthrough key must be a variabl
- WASM runtime does not support shell commands. Use `execute_m
- Failed to resolve host '{host}'
- Encrypted value too short (missing nonce)
- Key file must contain exactly 32 bytes (got {})
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/0dd5c7b94b4e0c4e.
Report an issue: GitHub.