juanfont/headscale · error
generating random IP: %w
Error message
generating random IP: %w
What it means
randomNext picks a uniform random offset within the prefix using crypto/rand's rand.Int over the range size. This error means the system entropy source returned an error — the read from rand.Reader failed. Single-address prefixes (from == to) are short-circuited before this call, so this specifically signals an entropy/reader fault.
Source
Thrown at hscontrol/db/ip.go:266
var from, to big.Int
from.SetBytes(fromIP.AsSlice())
to.SetBytes(toIP.AsSlice())
// Find the max, this is how we can do "random range",
// get the "max" as 0 -> to - from and then add back from
// after.
tempMax := big.NewInt(0).Sub(&to, &from)
// A single-address prefix (/32 or /128) has from == to, so tempMax is 0 and
// rand.Int would panic on a non-positive bound. Return the sole address.
if tempMax.Sign() <= 0 {
return fromIP, nil
}
out, err := rand.Int(rand.Reader, tempMax)
if err != nil {
return netip.Addr{}, fmt.Errorf("generating random IP: %w", err)
}
valInRange := big.NewInt(0).Add(&from, out)
// big.Int.Bytes() strips leading zero bytes, so a value with a zero high
// byte yields a too-short slice that AddrFromSlice rejects. Pad to the
// prefix's address width.
ip, ok := netip.AddrFromSlice(valInRange.FillBytes(make([]byte, len(fromIP.AsSlice()))))
if !ok {
return netip.Addr{}, errGeneratedIPBytesInvalid
}
if !pfx.Contains(ip) {
return netip.Addr{}, fmt.Errorf(
"%w: ip(%s) not in prefix(%s)",
errGeneratedIPNotInPrefix,
ip.String(),
pfx.String(),View on GitHub (pinned to 565fd254d0)
Solutions
- Use sequential allocation strategy to remove the dependency on randomness.
- Loosen the container security profile to allow getrandom(2) (Docker's default seccomp already does).
- Ensure the host kernel RNG is initialized before headscale starts (check `cat /proc/sys/kernel/random/entropy_avail`).
Defensive patterns
Strategy: fallback
Validate before calling
import "crypto/rand"
func entropyHealthy() error {
b := make([]byte, 16)
if _, err := rand.Read(b); err != nil {
return fmt.Errorf("entropy source unavailable: %w", err)
}
return nil
} Try / catch
// errors.Is on the wrapped crypto/rand error; fall back to sequential // allocation — never to math/rand for address selection in security- // relevant deployments, though for pure uniqueness sequential is fine.
Prevention
- Allow getrandom(2) in container seccomp profiles.
- Wait for kernel RNG initialization before starting services at early boot.
When it happens
Trigger: rand.Reader read failure: blocked /dev/random in a restricted sandbox, a broken getrandom(2) under a strict seccomp/apparmor profile, or kernel RNG not yet initialized early in boot (rare on modern Linux).
Common situations: Minimal Docker images with restrictive default seccomp denying getrandom; freshly booted VMs; nested virtualization environments; never on correctly configured modern hosts.
Related errors
- getting random IP: %w
- failed to generate API key
- failed to allocate IP
- no IPv4 or IPv6 prefix configured, minimum one prefix is req
- generating registration ID: %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/a50a0b67b27838b3.
Report an issue: GitHub.