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

  1. Verify /dev/urandom exists and is readable inside the container/exec context: ls -l /dev/urandom.
  2. Fix the container spec: do not mask /dev/urandom, allow the getrandom syscall in seccomp, use a standard base image.
  3. Delay registration until after boot entropy initialization on embedded targets.
  4. 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

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


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/28373ab29eeca3b0. Report an issue: GitHub.