juanfont/headscale · error
building initial IP Set: %w
Error message
building initial IP Set: %w
What it means
After adding all reserved and used addresses to a netipx.IPSetBuilder, the constructor calls IPSet() once to validate. Failure means the accumulated set is internally inconsistent — practically, that configured prefixes contain invalid or contradictory addresses (e.g. a misparsed ip_prefixes entry producing a bad reserved address).
Source
Thrown at hscontrol/db/ip.go:129
}
// Fetch all the IP Addresses currently handed out from the Database
// and add them to the used IP set.
for _, addrStr := range append(v4s, v6s...) {
if addrStr.Valid {
addr, err := netip.ParseAddr(addrStr.String)
if err != nil {
return nil, fmt.Errorf("parsing IP address from database: %w", err)
}
ips.Add(addr)
}
}
// Build the initial IPSet to validate that we can use it.
_, err := ips.IPSet()
if err != nil {
return nil, fmt.Errorf(
"building initial IP Set: %w",
err,
)
}
ret.usedIPs = ips
return &ret, nil
}
func (i *IPAllocator) Next() (*netip.Addr, *netip.Addr, error) {
var (
err error
ret4 *netip.Addr
ret6 *netip.Addr
)
if i.prefix4 != nil {View on GitHub (pinned to 565fd254d0)
Solutions
- Validate every entry in ip_prefixes is a well-formed CIDR of the intended family.
- Reset to the defaults (100.64.0.0/10 and fd7a:115c:a1e0::/48) and confirm startup, then re-apply custom prefixes one by one.
- Ensure prefixes do not overlap each other.
Example fix
# before (config.yaml) ip_prefixes: - 100.64.0.0/10 - fd7a:115c:a1e0::49 # typo, not a /48 prefix # after ip_prefixes: - 100.64.0.0/10 - fd7a:115c:a1e0::/48
Defensive patterns
Strategy: validation
Validate before calling
import "net/netip"
func validatePrefixes(raw []string) error {
for _, s := range raw {
p, err := netip.ParsePrefix(strings.TrimSpace(s))
if err != nil {
return fmt.Errorf("invalid prefix %q: %w", s, err)
}
if p != p.Masked() {
return fmt.Errorf("prefix %q has host bits set", s)
}
}
return nil
} Try / catch
// Config-level failure with no runtime recovery: fix ip_prefixes and // restart. Validate prefixes in a config linter before deploy.
Prevention
- Lint ip_prefixes as masked CIDRs in CI.
- Prefer the default prefixes unless address space forces customization.
When it happens
Trigger: ip_prefixes config containing a value that netipx cannot reconcile into a ranged set — invalid CIDR, mixed-family bytes fed into the builder, or a zero-value prefix producing an invalid endpoint via GetIPPrefixEndpoints.
Common situations: Hand-edited ip_prefixes with a typo ('100.64.0.0/10 ' with space, 'fd7a:115c:a1e0::/48' mistyped); config migrated from an old format; environment variable override mistakes.
Related errors
- failed to allocate IP
- no IPv4 or IPv6 prefix configured, minimum one prefix is req
- allocating IPv4 address: %w
- allocating IPv6 address: %w
- %w: ip(%s) not in prefix(%s)
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/fbdb5a068fccc002.
Report an issue: GitHub.