juanfont/headscale · error
generating registration ID: %w
Error message
generating registration ID: %w
What it means
Wraps a failure of types.NewAuthID() at the start of handleRegisterInteractive (hscontrol/auth.go:486). NewAuthID builds the registration ID as a fixed prefix plus 24 random hex chars via rands.HexString; the only failure mode is the entropy source (crypto/rand) being unavailable to the process. This is a defensive guard that essentially never fires on a healthy system.
Source
Thrown at hscontrol/auth.go:482
}
log.Trace().
Caller().
Interface("reg.resp", resp).
Interface("reg.req", req).
EmbedObject(node).
Msg("RegisterResponse")
return resp, nil
}
func (h *Headscale) handleRegisterInteractive(
req tailcfg.RegisterRequest,
machineKey key.MachinePublic,
) (*tailcfg.RegisterResponse, error) {
authID, err := types.NewAuthID()
if err != nil {
return nil, fmt.Errorf("generating registration ID: %w", err)
}
if req.Hostinfo == nil {
log.Warn().
Str("machine.key", machineKey.ShortString()).
Str("node.key", req.NodeKey.ShortString()).
Msg("Received registration request with nil hostinfo, generated default hostname")
} else if req.Hostinfo.Hostname == "" {
log.Warn().
Str("machine.key", machineKey.ShortString()).
Str("node.key", req.NodeKey.ShortString()).
Msg("Received registration request with empty hostname, generated default")
}
authRegReq := types.NewRegisterAuthRequest(
registrationDataFromRequest(req, machineKey),
)
View on GitHub (pinned to 565fd254d0)
Solutions
- Verify /dev/urandom exists and is readable inside the container/exec context: ls -l /dev/urandom.
- Fix the container spec: do not mask /dev/urandom, allow the getrandom syscall in seccomp, use a standard base image.
- Delay registration until after boot entropy initialization on embedded targets.
- As a workaround, use pre-auth-key registration, which does not generate an interactive AuthID.
Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight: entropy source available.
func entropyAvailable() error {
b := make([]byte, 16)
_, err := crand.Read(b)
return err
} Try / catch
resp, err := h.handleRegister(req, mk)
if err != nil && strings.Contains(err.Error(), "generating registration ID") {
// entropy/getrandom unavailable: fix container spec (/dev/urandom, seccomp), then retry login
} Prevention
- Do not mask /dev/urandom in containers; allow the getrandom syscall in seccomp profiles.
- Delay client enrollment until after boot entropy init on embedded hosts.
- Use pre-auth keys where interactive registration is impractical.
When it happens
Trigger: Interactive registration (`tailscale login` without an auth key) on a host where crypto/rand cannot be read: getrandom(2) blocked/unavailable, a broken container runtime, or an OS with a misconfigured entropy device.
Common situations: Exotic minimal containers (scratch images missing /dev/urandom, odd seccomp profiles blocking getrandom); early-boot registration on entropy-starved embedded systems. On normal Linux/macOS hosts this does not occur because getrandom never blocks after initialization.
Related errors
- handling logout: %w
- handling existing node: %w
- handling register with auth key: %w
- handling register interactive: %w
- MOCKOIDC_CLIENT_SECRET not defined
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/28373ab29eeca3b0.
Report an issue: GitHub.