juanfont/headscale · error

allocating IPv6 address: %w

Error message

allocating IPv6 address: %w

What it means

Same as 415 for the IPv6 family: Next() could not allocate a v6 address from the configured v6 prefix. Includes the random-strategy failure path (randomNext error) in addition to exhaustion.

Source

Thrown at hscontrol/db/ip.go:157

func (i *IPAllocator) Next() (*netip.Addr, *netip.Addr, error) {
	var (
		err  error
		ret4 *netip.Addr
		ret6 *netip.Addr
	)

	if i.prefix4 != nil {
		ret4, err = i.allocateNext(&i.prev4, i.prefix4)
		if err != nil {
			return nil, nil, fmt.Errorf("allocating IPv4 address: %w", err)
		}
	}

	if i.prefix6 != nil {
		ret6, err = i.allocateNext(&i.prev6, i.prefix6)
		if err != nil {
			return nil, nil, fmt.Errorf("allocating IPv6 address: %w", err)
		}
	}

	return ret4, ret6, nil
}

var ErrCouldNotAllocateIP = errors.New("failed to allocate IP")

// allocateNext allocates the next address from prefix under i.mu, advancing
// prev so a run of allocations (e.g. BackfillNodeIPs) does not rescan
// already-issued addresses, and so prev is read under the lock rather than in
// the caller's frame.
func (i *IPAllocator) allocateNext(prev *netip.Addr, prefix *netip.Prefix) (*netip.Addr, error) {
	i.mu.Lock()
	defer i.mu.Unlock()

	ret, err := i.next(*prev, prefix)
	if err != nil {

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Widen or restore the IPv6 prefix (default fd7a:115c:a1e0::/48).
  2. Inspect the chained error: if it comes from the random strategy, switch allocation strategy to sequential (ip_allocation_strategy) to bypass.
  3. Prune expired/deleted nodes to reclaim addresses.

Example fix

# before
ip_prefixes:
  - 100.64.0.0/10
  - fd7a:115c:a1e0::/126 # 4 addresses, exhausted

# after
ip_prefixes:
  - 100.64.0.0/10
  - fd7a:115c:a1e0::/48
Defensive patterns

Strategy: fallback

Validate before calling

// Mirror of the v4 check applied to the v6 prefix:
// ensure fd7a:115c:a1e0::/48 (or wider) and nodeCount well below 2^80.

Try / catch

// Fall back to v4-only or sequential strategy while the v6 prefix is
// enlarged; retry registration after config reload.

Prevention

When it happens

Trigger: v6 prefix exhausted (only realistic with a deliberately tiny prefix), or the random strategy failing to produce a usable start address (chained error from randomNext — see 417/418).

Common situations: Custom narrow fd7a::/120-style prefixes; removing the default v6 prefix while nodes still request dual-stack.

Related errors


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