astrid-runtime/astrid · error
OS CSPRNG unavailable while generating default keypair name
Error message
OS CSPRNG unavailable while generating default keypair name
What it means
default_name generates a random key-<hex> name using the OS CSPRNG via getrandom (SysRng.try_fill_bytes). If the operating system randomness source is unavailable, the function panics with this expect message instead of returning a keypair name. The randomness is considered a hard requirement for key generation.
Solutions
- Fix the environment so getrandom works (restore /dev/urandom, relax seccomp rules blocking getrandom(2))
- Pass an explicit keypair name so default_name is never invoked
- Retry after the system RNG is available (e.g. after boot completes)
- Report/upgrade if running on a platform whose RNG syscall is unsupported
Example fix
// before astrid keypair new // after astrid keypair new --name my-key
Defensive patterns
Strategy: fallback
Validate before calling
// probe RNG availability before invoking keypair commands let mut b = [0u8; 1]; getrandom::getrandom(&mut b).map_err(|_| "OS CSPRNG unavailable")?;
Try / catch
// the library panics, so guard the entry point
let out = Command::new("astrid").args(["keypair", "new"]).output()?;
if !out.status.success()
&& String::from_utf8_lossy(&out.stderr).contains("OS CSPRNG unavailable") {
eprintln!("RNG unavailable; pass an explicit --name or fix entropy");
} Prevention
- Pass an explicit keypair name in automated/CI environments
- Avoid running key generation in seccomp-restricted containers without getrandom
- Monitor entropy/RNG health on minimal or early-boot systems
When it happens
Trigger: Calling commands that need an auto-generated keypair name (e.g. astrid keypair new without --name) on a system where /dev/urandom or getrandom(2) fails — exhausted entropy blocking, seccomp/container policies blocking getrandom, or a broken /dev/urandom.
Common situations: Hardened containers/jails that seccomp-filter getrandom; early-boot environments before the RNG is seeded; chroots missing /dev/urandom; VMs with unusual entropy configuration.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- OS CSPRNG unavailable while generating gateway signing key
- OS CSPRNG unavailable while generating invite suffix
- OS CSPRNG unavailable while generating invite token
- alice
- decode public key hex
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/25b762b4bedaf5cd.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-cli/src/commands/keypair.rs:600
name.len()
);
}
// Lowercase letters, digits, dash. Same posture as principal ids;
// also avoids path-separator / shell-meta surprises.
if !name
.chars()
.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-')
{
bail!("keypair name {name:?} contains invalid chars; only a-z, 0-9, '-' are allowed");
}
Ok(())
}
fn default_name() -> String {
let mut bytes = [0u8; 4];
SysRng
.try_fill_bytes(&mut bytes)
.expect("OS CSPRNG unavailable while generating default keypair name");
format!("key-{}", hex::encode(bytes))
}
fn fingerprint_pubkey(hex_pub: &str) -> Result<String> {
PublicKeyFingerprint::from_ed25519_hex(hex_pub)
.map(PublicKeyFingerprint::into_inner)
.map_err(|e| anyhow::anyhow!("fingerprint Ed25519 public key: {e}"))
}
/// Convert a 64-char hex ed25519 public key into the `ed25519:<base64>`
/// wire form that `[distro.signing].pubkey`, `astrid distro seal`, and
/// the distro trust store consume. Reuses `astrid-crypto`'s encoder so
/// the base64 variant matches the verifier byte-for-byte.
fn pubkey_hex_to_wire(pub_hex: &str) -> Result<String> {
let pk = astrid_crypto::PublicKey::from_hex(pub_hex.trim())
.map_err(|e| anyhow::anyhow!("decode public key hex: {e}"))?;
Ok(format!("ed25519:{}", pk.to_base64()))
}View on GitHub (pinned to affd8760f4)