juanfont/headscale · error
getting random IP: %w
Error message
getting random IP: %w
What it means
Inside allocateNext, when the strategy is IPAllocationStrategyRandom the start address is chosen by randomNext(). This error wraps a failure of that call — the crypto/rand-based pick of a random offset inside the prefix could not be completed.
Source
Thrown at hscontrol/db/ip.go:197
*prev = *ret
return ret, nil
}
func (i *IPAllocator) next(prev netip.Addr, prefix *netip.Prefix) (*netip.Addr, error) {
var (
err error
ip netip.Addr
)
switch i.strategy {
case types.IPAllocationStrategySequential:
// Get the first IP in our prefix
ip = prev.Next()
case types.IPAllocationStrategyRandom:
ip, err = randomNext(*prefix)
if err != nil {
return nil, fmt.Errorf("getting random IP: %w", err)
}
}
// TODO(kradalby): maybe this can be done less often.
set, err := i.usedIPs.IPSet()
if err != nil {
return nil, err
}
// Walk forward from the starting address until a free, non-reserved
// address inside the prefix is found. The random strategy only picks the
// starting point at random and then scans deterministically: this keeps
// the loop finite, so an exhausted prefix returns ErrCouldNotAllocateIP
// instead of re-drawing in-prefix addresses forever under i.mu.
start := ip
for {
if prefix.Contains(ip) && !set.Contains(ip) && !isTailscaleReservedIP(ip) {
i.usedIPs.Add(ip)View on GitHub (pinned to 565fd254d0)
Solutions
- Switch ip_allocation_strategy to sequential — deterministic and avoids the entropy path entirely.
- Fix the environment's entropy: ensure /dev/urandom is available and not blocked by the container runtime/seccomp.
- Check dmesg/kernel logs for RNG initialization failures on the host.
Example fix
# before (config.yaml) ip_allocation_strategy: random # after ip_allocation_strategy: sequential
Defensive patterns
Strategy: fallback
Validate before calling
// Environment pre-check for the random strategy: // cat /proc/sys/kernel/random/entropy_avail # expect > 128 // Or in Go: read 16 bytes from crypto/rand and time it.
Try / catch
// Catch and fall back to sequential allocation for that request:
// ip, err := alloc.Next()
// if err != nil && strings.Contains(err.Error(), "getting random IP") {
// ip, err = sequentialAlloc.Next() // or reconfigure strategy and retry
// } Prevention
- Prefer sequential strategy in constrained/sandboxed environments.
- Verify /dev/urandom availability in container images.
When it happens
Trigger: rand.Int(rand.Reader, ...) failing (error 418's cause: entropy source error), or — via the chained error — the generated address failing prefix containment checks. Reached only when ip_allocation_strategy is set to random.
Common situations: Containers/VMs with a depleted or blocked entropy source (/dev/random blocking in restricted environments); rare in modern kernels, more common in minimal chroots or certain seccomp profiles.
Related errors
- generating 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/567efabbfffad175.
Report an issue: GitHub.